Mon Mar 2 16:47:11 1998 Philippe De Muyter <phdm@macqel.be>
[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));
f27bb101
MM
38void d30v_frame_find_saved_regs_offsets PARAMS ((struct frame_info *fi,
39 struct frame_saved_regs *fsr));
45a70ed6 40static void d30v_pop_dummy_frame PARAMS ((struct frame_info *fi));
5d62f957
MM
41static void d30v_print_flags PARAMS ((void));
42static void print_flags_command PARAMS ((char *, int));
45a70ed6 43
7359fb1d
DT
44/* the following defines assume:
45 fp is r61, lr is r62, sp is r63, and ?? is r22
46 if that changes, they will need to be updated */
47
48#define OP_MASK_ALL_BUT_RA 0x0ffc0fff /* throw away Ra, keep the rest */
49
50#define OP_STW_SPM 0x054c0fc0 /* stw Ra, @(sp-) */
51#define OP_STW_SP_R0 0x05400fc0 /* stw Ra, @(sp,r0) */
52#define OP_STW_SP_IMM0 0x05480fc0 /* st Ra, @(sp, 0x0) */
53#define OP_STW_R22P_R0 0x05440580 /* stw Ra, @(r22+,r0) */
54
55#define OP_ST2W_SPM 0x056c0fc0 /* st2w Ra, @(sp-) */
56#define OP_ST2W_SP_R0 0x05600fc0 /* st2w Ra, @(sp, r0) */
57#define OP_ST2W_SP_IMM0 0x05680fc0 /* st2w Ra, @(sp, 0x0) */
58#define OP_ST2W_R22P_R0 0x05640580 /* st2w Ra, @(r22+, r0) */
59
60#define OP_MASK_OPCODE 0x0ffc0000 /* just the opcode, ign operands */
61#define OP_NOP 0x00f00000 /* nop */
62
63#define OP_MASK_ALL_BUT_IMM 0x0fffffc0 /* throw away imm, keep the rest */
64#define OP_SUB_SP_IMM 0x082bffc0 /* sub sp,sp,imm */
65#define OP_ADD_SP_IMM 0x080bffc0 /* add sp,sp,imm */
66#define OP_ADD_R22_SP_IMM 0x08096fc0 /* add r22,sp,imm */
67#define OP_STW_FP_SP_IMM 0x054bdfc0 /* stw fp,@(sp,imm) */
36985eca 68#define OP_OR_SP_R0_IMM 0x03abf000 /* or sp,r0,imm */
7359fb1d
DT
69
70/* no mask */
71#define OP_OR_FP_R0_SP 0x03a3d03f /* or fp,r0,sp */
72#define OP_OR_FP_SP_R0 0x03a3dfc0 /* or fp,sp,r0 */
73#define OP_OR_FP_IMM0_SP 0x03abd03f /* or fp,0x0,sp */
74#define OP_STW_FP_R22P_R0 0x0547d580 /* stw fp,@(r22+,r0) */
75#define OP_STW_LR_R22P_R0 0x0547e580 /* stw lr,@(r22+,r0) */
76
77#define OP_MASK_OP_AND_RB 0x0ff80fc0 /* keep op and rb,throw away rest */
78#define OP_STW_SP_IMM 0x05480fc0 /* stw Ra,@(sp,imm) */
79#define OP_ST2W_SP_IMM 0x05680fc0 /* st2w Ra,@(sp,imm) */
80#define OP_STW_FP_IMM 0x05480f40 /* stw Ra,@(fp,imm) */
81#define OP_STW_FP_R0 0x05400f40 /* stw Ra,@(fp,r0) */
82
83#define OP_MASK_FM_BIT 0x80000000
84#define OP_MASK_CC_BITS 0x70000000
85#define OP_MASK_SUB_INST 0x0fffffff
86
87#define EXTRACT_RA(op) (((op) >> 12) & 0x3f)
88#define EXTRACT_RB(op) (((op) >> 6) & 0x3f)
89#define EXTRACT_RC(op) (((op) & 0x3f)
90#define EXTRACT_UIMM6(op) ((op) & 0x3f)
91#define EXTRACT_IMM6(op) ((((int)EXTRACT_UIMM6(op)) << 26) >> 26)
92#define EXTRACT_IMM26(op) ((((op)&0x0ff00000) >> 2) | ((op)&0x0003ffff))
93#define EXTRACT_IMM32(opl, opr) ((EXTRACT_UIMM6(opl) << 26)|EXTRACT_IMM26(opr))
94
45a70ed6
SG
95/* Discard from the stack the innermost frame, restoring all saved
96 registers. */
97
98void
99d30v_pop_frame ()
100{
101 struct frame_info *frame = get_current_frame ();
102 CORE_ADDR fp;
103 int regnum;
104 struct frame_saved_regs fsr;
105 char raw_buffer[8];
106
107 fp = FRAME_FP (frame);
108 if (frame->dummy)
109 {
110 d30v_pop_dummy_frame(frame);
111 return;
112 }
113
114 /* fill out fsr with the address of where each */
115 /* register was stored in the frame */
116 get_frame_saved_regs (frame, &fsr);
117
118 /* now update the current registers with the old values */
119 for (regnum = A0_REGNUM; regnum < A0_REGNUM+2 ; regnum++)
120 {
121 if (fsr.regs[regnum])
122 {
123 read_memory (fsr.regs[regnum], raw_buffer, 8);
124 write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 8);
125 }
126 }
127 for (regnum = 0; regnum < SP_REGNUM; regnum++)
128 {
129 if (fsr.regs[regnum])
130 {
7359fb1d 131 write_register (regnum, read_memory_unsigned_integer (fsr.regs[regnum], 4));
45a70ed6
SG
132 }
133 }
134 if (fsr.regs[PSW_REGNUM])
135 {
7359fb1d 136 write_register (PSW_REGNUM, read_memory_unsigned_integer (fsr.regs[PSW_REGNUM], 4));
45a70ed6
SG
137 }
138
7359fb1d 139 write_register (PC_REGNUM, read_register(LR_REGNUM));
45a70ed6
SG
140 write_register (SP_REGNUM, fp + frame->size);
141 target_store_registers (-1);
142 flush_cached_frames ();
143}
144
145static int
146check_prologue (op)
7359fb1d 147 unsigned long op;
45a70ed6 148{
7359fb1d
DT
149 /* add sp,sp,imm -- observed */
150 if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_SP_IMM)
45a70ed6
SG
151 return 1;
152
7359fb1d
DT
153 /* add r22,sp,imm -- observed */
154 if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_R22_SP_IMM)
45a70ed6
SG
155 return 1;
156
7359fb1d
DT
157 /* or fp,r0,sp -- observed */
158 if (op == OP_OR_FP_R0_SP)
45a70ed6
SG
159 return 1;
160
7359fb1d
DT
161 /* nop */
162 if ((op & OP_MASK_OPCODE) == OP_NOP)
45a70ed6
SG
163 return 1;
164
7359fb1d
DT
165 /* stw Ra,@(sp,r0) */
166 if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0)
45a70ed6
SG
167 return 1;
168
7359fb1d
DT
169 /* stw Ra,@(sp,0x0) */
170 if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0)
45a70ed6
SG
171 return 1;
172
7359fb1d
DT
173 /* st2w Ra,@(sp,r0) */
174 if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_R0)
175 return 1;
176
177 /* st2w Ra,@(sp,0x0) */
178 if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0)
179 return 1;
180
181 /* stw fp, @(r22+,r0) -- observed */
182 if (op == OP_STW_FP_R22P_R0)
183 return 1;
184
185 /* stw r62, @(r22+,r0) -- observed */
186 if (op == OP_STW_LR_R22P_R0)
187 return 1;
188
189 /* stw Ra, @(fp,r0) -- observed */
190 if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_FP_R0)
191 return 1; /* first arg */
192
193 /* stw Ra, @(fp,imm) -- observed */
194 if ((op & OP_MASK_OP_AND_RB) == OP_STW_FP_IMM)
195 return 1; /* second and subsequent args */
196
197 /* stw fp,@(sp,imm) -- observed */
198 if ((op & OP_MASK_ALL_BUT_IMM) == OP_STW_FP_SP_IMM)
199 return 1;
200
201 /* st2w Ra,@(r22+,r0) */
202 if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_R22P_R0)
45a70ed6
SG
203 return 1;
204
7359fb1d
DT
205 /* stw Ra, @(sp-) */
206 if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SPM)
207 return 1;
208
209 /* st2w Ra, @(sp-) */
210 if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SPM)
211 return 1;
212
213 /* sub.? sp,sp,imm */
214 if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM)
215 return 1;
216
45a70ed6
SG
217 return 0;
218}
219
220CORE_ADDR
221d30v_skip_prologue (pc)
222 CORE_ADDR pc;
223{
7359fb1d
DT
224 unsigned long op[2];
225 unsigned long opl, opr; /* left / right sub operations */
226 unsigned long fm0, fm1; /* left / right mode bits */
227 unsigned long cc0, cc1;
228 unsigned long op1, op2;
45a70ed6
SG
229 CORE_ADDR func_addr, func_end;
230 struct symtab_and_line sal;
231
232 /* If we have line debugging information, then the end of the */
233 /* prologue should the first assembly instruction of the first source line */
234 if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
235 {
236 sal = find_pc_line (func_addr, 0);
237 if ( sal.end && sal.end < func_end)
238 return sal.end;
239 }
240
7359fb1d 241 if (target_read_memory (pc, (char *)&op[0], 8))
45a70ed6
SG
242 return pc; /* Can't access it -- assume no prologue. */
243
244 while (1)
245 {
7359fb1d
DT
246 opl = (unsigned long)read_memory_integer (pc, 4);
247 opr = (unsigned long)read_memory_integer (pc+4, 4);
248
249 fm0 = (opl & OP_MASK_FM_BIT);
250 fm1 = (opr & OP_MASK_FM_BIT);
251
252 cc0 = (opl & OP_MASK_CC_BITS);
253 cc1 = (opr & OP_MASK_CC_BITS);
254
255 opl = (opl & OP_MASK_SUB_INST);
256 opr = (opr & OP_MASK_SUB_INST);
257
258 if (fm0 && fm1)
45a70ed6 259 {
7359fb1d
DT
260 /* long instruction (opl contains the opcode) */
261 if (((opl & OP_MASK_ALL_BUT_IMM) != OP_ADD_SP_IMM) && /* add sp,sp,imm */
262 ((opl & OP_MASK_ALL_BUT_IMM) != OP_ADD_R22_SP_IMM) && /* add r22,sp,imm */
263 ((opl & OP_MASK_OP_AND_RB) != OP_STW_SP_IMM) && /* stw Ra, @(sp,imm) */
264 ((opl & OP_MASK_OP_AND_RB) != OP_ST2W_SP_IMM)) /* st2w Ra, @(sp,imm) */
45a70ed6
SG
265 break;
266 }
267 else
268 {
269 /* short instructions */
7359fb1d 270 if (fm0 && !fm1)
45a70ed6 271 {
7359fb1d
DT
272 op1 = opr;
273 op2 = opl;
45a70ed6
SG
274 }
275 else
276 {
7359fb1d
DT
277 op1 = opl;
278 op2 = opr;
45a70ed6
SG
279 }
280 if (check_prologue(op1))
281 {
282 if (!check_prologue(op2))
283 {
284 /* if the previous opcode was really part of the prologue */
285 /* and not just a NOP, then we want to break after both instructions */
7359fb1d
DT
286 if ((op1 & OP_MASK_OPCODE) != OP_NOP)
287 pc += 8;
45a70ed6
SG
288 break;
289 }
290 }
291 else
292 break;
293 }
7359fb1d 294 pc += 8;
45a70ed6
SG
295 }
296 return pc;
297}
298
36985eca
DT
299static int end_of_stack;
300
45a70ed6
SG
301/* Given a GDB frame, determine the address of the calling function's frame.
302 This will be used to create a new GDB frame struct, and then
303 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
304*/
305
306CORE_ADDR
307d30v_frame_chain (frame)
308 struct frame_info *frame;
309{
310 struct frame_saved_regs fsr;
311
312 d30v_frame_find_saved_regs (frame, &fsr);
313
36985eca
DT
314 if (end_of_stack)
315 return (CORE_ADDR)0;
316
45a70ed6
SG
317 if (frame->return_pc == IMEM_START)
318 return (CORE_ADDR)0;
319
320 if (!fsr.regs[FP_REGNUM])
321 {
322 if (!fsr.regs[SP_REGNUM] || fsr.regs[SP_REGNUM] == STACK_START)
323 return (CORE_ADDR)0;
324
325 return fsr.regs[SP_REGNUM];
326 }
327
7359fb1d 328 if (!read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4))
45a70ed6
SG
329 return (CORE_ADDR)0;
330
7ae2b433 331 return read_memory_unsigned_integer(fsr.regs[FP_REGNUM],4);
45a70ed6
SG
332}
333
334static int next_addr, uses_frame;
7359fb1d 335static int frame_size;
45a70ed6
SG
336
337static int
338prologue_find_regs (op, fsr, addr)
7359fb1d 339 unsigned long op;
45a70ed6
SG
340 struct frame_saved_regs *fsr;
341 CORE_ADDR addr;
342{
343 int n;
7359fb1d 344 int offset;
45a70ed6 345
7359fb1d
DT
346 /* add sp,sp,imm -- observed */
347 if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_SP_IMM)
45a70ed6 348 {
7359fb1d
DT
349 offset = EXTRACT_IMM6(op);
350 /*next_addr += offset;*/
351 frame_size += -offset;
45a70ed6
SG
352 return 1;
353 }
354
7359fb1d
DT
355 /* add r22,sp,imm -- observed */
356 if ((op & OP_MASK_ALL_BUT_IMM) == OP_ADD_R22_SP_IMM)
45a70ed6 357 {
7359fb1d
DT
358 offset = EXTRACT_IMM6(op);
359 next_addr = (offset - frame_size);
360 return 1;
361 }
362
363 /* stw Ra, @(fp, offset) -- observed */
364 if ((op & OP_MASK_OP_AND_RB) == OP_STW_FP_IMM)
365 {
366 n = EXTRACT_RA(op);
367 offset = EXTRACT_IMM6(op);
368 fsr->regs[n] = (offset - frame_size);
45a70ed6
SG
369 return 1;
370 }
371
7359fb1d
DT
372 /* stw Ra, @(fp, r0) -- observed */
373 if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_FP_R0)
45a70ed6 374 {
7359fb1d
DT
375 n = EXTRACT_RA(op);
376 fsr->regs[n] = (- frame_size);
45a70ed6
SG
377 return 1;
378 }
379
7359fb1d
DT
380 /* or fp,0,sp -- observed */
381 if ((op == OP_OR_FP_R0_SP) ||
382 (op == OP_OR_FP_SP_R0) ||
383 (op == OP_OR_FP_IMM0_SP))
45a70ed6
SG
384 {
385 uses_frame = 1;
386 return 1;
387 }
388
389 /* nop */
7359fb1d 390 if ((op & OP_MASK_OPCODE) == OP_NOP)
45a70ed6
SG
391 return 1;
392
7359fb1d
DT
393 /* stw Ra,@(r22+,r0) -- observed */
394 if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_R22P_R0)
395 {
396 n = EXTRACT_RA(op);
397 fsr->regs[n] = next_addr;
398 next_addr += 4;
399 return 1;
400 }
401#if 0 /* subsumed in pattern above */
402 /* stw fp,@(r22+,r0) -- observed */
403 if (op == OP_STW_FP_R22P_R0)
404 {
405 fsr->regs[FP_REGNUM] = next_addr; /* XXX */
406 next_addr += 4;
407 return 1;
408 }
409
410 /* stw r62,@(r22+,r0) -- observed */
411 if (op == OP_STW_LR_R22P_R0)
412 {
413 fsr->regs[LR_REGNUM] = next_addr;
414 next_addr += 4;
415 return 1;
416 }
417#endif
418 /* st2w Ra,@(r22+,r0) -- observed */
419 if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_R22P_R0)
420 {
421 n = EXTRACT_RA(op);
422 fsr->regs[n] = next_addr;
423 fsr->regs[n+1] = next_addr + 4;
424 next_addr += 8;
425 return 1;
426 }
427
428 /* stw rn, @(sp-) */
429 if ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SPM)
430 {
431 n = EXTRACT_RA(op);
432 fsr->regs[n] = next_addr;
433 next_addr -= 4;
434 return 1;
435 }
436
437 /* st2w Ra, @(sp-) */
438 else if ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SPM)
45a70ed6 439 {
7359fb1d 440 n = EXTRACT_RA(op);
45a70ed6 441 fsr->regs[n] = next_addr;
7359fb1d
DT
442 fsr->regs[n+1] = next_addr+4;
443 next_addr -= 8;
444 return 1;
445 }
446
447 /* sub sp,sp,imm */
448 if ((op & OP_MASK_ALL_BUT_IMM) == OP_SUB_SP_IMM)
449 {
450 offset = EXTRACT_IMM6(op);
7ae2b433 451 frame_size += -offset;
45a70ed6
SG
452 return 1;
453 }
454
7ae2b433 455 /* st rn, @(sp,0) -- observed */
7359fb1d
DT
456 if (((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_R0) ||
457 ((op & OP_MASK_ALL_BUT_RA) == OP_STW_SP_IMM0))
45a70ed6 458 {
7359fb1d 459 n = EXTRACT_RA(op);
7ae2b433 460 fsr->regs[n] = (- frame_size);
7359fb1d
DT
461 return 1;
462 }
463
464 /* st2w rn, @(sp,0) */
465 if (((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_R0) ||
466 ((op & OP_MASK_ALL_BUT_RA) == OP_ST2W_SP_IMM0))
467 {
468 n = EXTRACT_RA(op);
7ae2b433
DT
469 fsr->regs[n] = (- frame_size);
470 fsr->regs[n+1] = (- frame_size) + 4;
45a70ed6
SG
471 return 1;
472 }
473
36985eca
DT
474 /* stw fp,@(sp,imm) -- observed */
475 if ((op & OP_MASK_ALL_BUT_IMM) == OP_STW_FP_SP_IMM)
476 {
477 offset = EXTRACT_IMM6(op);
478 fsr->regs[FP_REGNUM] = (offset - frame_size);
479 return 1;
480 }
45a70ed6
SG
481 return 0;
482}
483
484/* Put here the code to store, into a struct frame_saved_regs, the
485 addresses of the saved registers of frame described by FRAME_INFO.
486 This includes special registers such as pc and fp saved in special
487 ways in the stack frame. sp is even more special: the address we
488 return for it IS the sp for the next frame. */
489void
490d30v_frame_find_saved_regs (fi, fsr)
491 struct frame_info *fi;
492 struct frame_saved_regs *fsr;
493{
494 CORE_ADDR fp, pc;
7359fb1d
DT
495 unsigned long opl, opr;
496 unsigned long op1, op2;
497 unsigned long fm0, fm1;
45a70ed6
SG
498 int i;
499
500 fp = fi->frame;
501 memset (fsr, 0, sizeof (*fsr));
502 next_addr = 0;
7359fb1d 503 frame_size = 0;
36985eca 504 end_of_stack = 0;
45a70ed6 505
cd44191e
DT
506 uses_frame = 0;
507
508 d30v_frame_find_saved_regs_offsets (fi, fsr);
509
510 fi->size = frame_size;
511
512 if (!fp)
513 fp = read_register(SP_REGNUM);
514
515 for (i=0; i<NUM_REGS-1; i++)
516 if (fsr->regs[i])
517 {
518 fsr->regs[i] = fsr->regs[i] + fp + frame_size;
519 }
520
521 if (fsr->regs[LR_REGNUM])
522 fi->return_pc = read_memory_unsigned_integer(fsr->regs[LR_REGNUM],4);
523 else
524 fi->return_pc = read_register(LR_REGNUM);
525
526 /* the SP is not normally (ever?) saved, but check anyway */
527 if (!fsr->regs[SP_REGNUM])
528 {
529 /* if the FP was saved, that means the current FP is valid, */
530 /* otherwise, it isn't being used, so we use the SP instead */
531 if (uses_frame)
532 fsr->regs[SP_REGNUM] = read_register(FP_REGNUM) + fi->size;
533 else
534 {
535 fsr->regs[SP_REGNUM] = fp + fi->size;
536 fi->frameless = 1;
537 fsr->regs[FP_REGNUM] = 0;
538 }
539 }
540}
541
542void
543d30v_frame_find_saved_regs_offsets (fi, fsr)
544 struct frame_info *fi;
545 struct frame_saved_regs *fsr;
546{
547 CORE_ADDR fp, pc;
548 unsigned long opl, opr;
549 unsigned long op1, op2;
550 unsigned long fm0, fm1;
551 int i;
552
553 fp = fi->frame;
554 memset (fsr, 0, sizeof (*fsr));
555 next_addr = 0;
556 frame_size = 0;
557 end_of_stack = 0;
558
45a70ed6
SG
559 pc = get_pc_function_start (fi->pc);
560
561 uses_frame = 0;
7ae2b433 562 while (pc < fi->pc)
45a70ed6 563 {
7359fb1d
DT
564 opl = (unsigned long)read_memory_integer (pc, 4);
565 opr = (unsigned long)read_memory_integer (pc+4, 4);
566
567 fm0 = (opl & OP_MASK_FM_BIT);
568 fm1 = (opr & OP_MASK_FM_BIT);
569
570 opl = (opl & OP_MASK_SUB_INST);
571 opr = (opr & OP_MASK_SUB_INST);
572
573 if (fm0 && fm1)
45a70ed6
SG
574 {
575 /* long instruction */
7359fb1d
DT
576 if ((opl & OP_MASK_ALL_BUT_IMM) == OP_ADD_SP_IMM)
577 {
578 /* add sp,sp,n */
579 long offset = EXTRACT_IMM32(opl, opr);
580 frame_size += -offset;
581 }
582 else if ((opl & OP_MASK_ALL_BUT_IMM) == OP_ADD_R22_SP_IMM)
45a70ed6 583 {
7359fb1d
DT
584 /* add r22,sp,offset */
585 long offset = EXTRACT_IMM32(opl,opr);
586 next_addr = (offset - frame_size);
45a70ed6 587 }
7359fb1d 588 else if ((opl & OP_MASK_OP_AND_RB) == OP_STW_SP_IMM)
45a70ed6 589 {
7359fb1d
DT
590 /* st Ra, @(sp,imm) */
591 long offset = EXTRACT_IMM32(opl, opr);
592 short n = EXTRACT_RA(opl);
593 fsr->regs[n] = (offset - frame_size);
45a70ed6 594 }
7359fb1d 595 else if ((opl & OP_MASK_OP_AND_RB) == OP_ST2W_SP_IMM)
45a70ed6 596 {
7359fb1d
DT
597 /* st2w Ra, @(sp,offset) */
598 long offset = EXTRACT_IMM32(opl, opr);
599 short n = EXTRACT_RA(opl);
600 fsr->regs[n] = (offset - frame_size);
601 fsr->regs[n+1] = (offset - frame_size) + 4;
45a70ed6 602 }
36985eca
DT
603 else if ((opl & OP_MASK_ALL_BUT_IMM) == OP_OR_SP_R0_IMM)
604 {
605 end_of_stack = 1;
606 }
45a70ed6
SG
607 else
608 break;
609 }
610 else
611 {
612 /* short instructions */
7359fb1d 613 if (fm0 && !fm1)
45a70ed6 614 {
7359fb1d
DT
615 op2 = opl;
616 op1 = opr;
45a70ed6
SG
617 }
618 else
619 {
7359fb1d
DT
620 op1 = opl;
621 op2 = opr;
45a70ed6
SG
622 }
623 if (!prologue_find_regs(op1,fsr,pc) || !prologue_find_regs(op2,fsr,pc))
624 break;
625 }
7359fb1d 626 pc += 8;
45a70ed6
SG
627 }
628
7359fb1d 629#if 0
cd44191e
DT
630 fi->size = frame_size;
631
36985eca 632 if (!fp)
7359fb1d 633 fp = read_register(SP_REGNUM);
cd44191e 634
45a70ed6
SG
635 for (i=0; i<NUM_REGS-1; i++)
636 if (fsr->regs[i])
637 {
7359fb1d 638 fsr->regs[i] = fsr->regs[i] + fp + frame_size;
45a70ed6
SG
639 }
640
641 if (fsr->regs[LR_REGNUM])
7359fb1d 642 fi->return_pc = read_memory_unsigned_integer(fsr->regs[LR_REGNUM],4);
45a70ed6 643 else
7359fb1d 644 fi->return_pc = read_register(LR_REGNUM);
45a70ed6 645
7ae2b433 646 /* the SP is not normally (ever?) saved, but check anyway */
45a70ed6
SG
647 if (!fsr->regs[SP_REGNUM])
648 {
649 /* if the FP was saved, that means the current FP is valid, */
650 /* otherwise, it isn't being used, so we use the SP instead */
651 if (uses_frame)
652 fsr->regs[SP_REGNUM] = read_register(FP_REGNUM) + fi->size;
653 else
654 {
655 fsr->regs[SP_REGNUM] = fp + fi->size;
656 fi->frameless = 1;
657 fsr->regs[FP_REGNUM] = 0;
658 }
659 }
cd44191e 660#endif
45a70ed6
SG
661}
662
663void
664d30v_init_extra_frame_info (fromleaf, fi)
665 int fromleaf;
666 struct frame_info *fi;
667{
668 struct frame_saved_regs dummy;
669
7359fb1d 670 if (fi->next && (fi->pc == 0))
45a70ed6
SG
671 fi->pc = fi->next->return_pc;
672
cd44191e
DT
673 d30v_frame_find_saved_regs_offsets (fi, &dummy);
674
675 if (uses_frame == 0)
676 fi->frameless = 1;
677 else
678 fi->frameless = 0;
679
680 if ((fi->next == 0) && (uses_frame == 0))
681 /* innermost frame and it's "frameless",
682 so the fi->frame field is wrong, fix it! */
683 fi->frame = read_sp ();
684
685 if (dummy.regs[LR_REGNUM])
686 {
687 /* it was saved, grab it! */
688 dummy.regs[LR_REGNUM] += (fi->frame + frame_size);
689 fi->return_pc = read_memory_unsigned_integer(dummy.regs[LR_REGNUM],4);
690 }
691 else
692 fi->return_pc = read_register(LR_REGNUM);
45a70ed6
SG
693}
694
7359fb1d
DT
695void
696d30v_init_frame_pc (fromleaf, prev)
697 int fromleaf;
698 struct frame_info *prev;
699{
700 /* default value, put here so we can breakpoint on it and
701 see if the default value is really the right thing to use */
702 prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) : \
703 prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
704}
705
45a70ed6
SG
706static void d30v_print_register PARAMS ((int regnum, int tabular));
707
708static void
709d30v_print_register (regnum, tabular)
710 int regnum;
711 int tabular;
712{
713 if (regnum < A0_REGNUM)
714 {
715 if (tabular)
716 printf_filtered ("%08x", read_register (regnum));
717 else
718 printf_filtered ("0x%x %d", read_register (regnum),
719 read_register (regnum));
720 }
721 else
722 {
723 char regbuf[MAX_REGISTER_RAW_SIZE];
724
725 read_relative_register_raw_bytes (regnum, regbuf);
726
727 val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0,
728 gdb_stdout, 'x', 1, 0, Val_pretty_default);
729
730 if (!tabular)
731 {
732 printf_filtered (" ");
733 val_print (REGISTER_VIRTUAL_TYPE (regnum), regbuf, 0,
734 gdb_stdout, 'd', 1, 0, Val_pretty_default);
735 }
736 }
737}
738
5d62f957
MM
739static void
740d30v_print_flags ()
741{
742 long psw = read_register (PSW_REGNUM);
743 printf_filtered ("flags #1");
744 printf_filtered (" (sm) %d", (psw & PSW_SM) != 0);
745 printf_filtered (" (ea) %d", (psw & PSW_EA) != 0);
746 printf_filtered (" (db) %d", (psw & PSW_DB) != 0);
747 printf_filtered (" (ds) %d", (psw & PSW_DS) != 0);
748 printf_filtered (" (ie) %d", (psw & PSW_IE) != 0);
749 printf_filtered (" (rp) %d", (psw & PSW_RP) != 0);
750 printf_filtered (" (md) %d\n", (psw & PSW_MD) != 0);
751
752 printf_filtered ("flags #2");
753 printf_filtered (" (f0) %d", (psw & PSW_F0) != 0);
754 printf_filtered (" (f1) %d", (psw & PSW_F1) != 0);
755 printf_filtered (" (f2) %d", (psw & PSW_F2) != 0);
756 printf_filtered (" (f3) %d", (psw & PSW_F3) != 0);
757 printf_filtered (" (s) %d", (psw & PSW_S) != 0);
758 printf_filtered (" (v) %d", (psw & PSW_V) != 0);
759 printf_filtered (" (va) %d", (psw & PSW_VA) != 0);
760 printf_filtered (" (c) %d\n", (psw & PSW_C) != 0);
761}
762
763static void
764print_flags_command (args, from_tty)
765 char *args;
766 int from_tty;
767{
768 d30v_print_flags ();
769}
770
45a70ed6
SG
771void
772d30v_do_registers_info (regnum, fpregs)
773 int regnum;
774 int fpregs;
775{
776 long long num1, num2;
5d62f957 777 long psw;
45a70ed6
SG
778
779 if (regnum != -1)
780 {
781 if (reg_names[0] == NULL || reg_names[0][0] == '\000')
782 return;
783
784 printf_filtered ("%s ", reg_names[regnum]);
785 d30v_print_register (regnum, 0);
786
787 printf_filtered ("\n");
788 return;
789 }
790
791 /* Have to print all the registers. Format them nicely. */
792
793 printf_filtered ("PC=");
794 print_address (read_pc (), gdb_stdout);
795
796 printf_filtered (" PSW=");
797 d30v_print_register (PSW_REGNUM, 1);
798
799 printf_filtered (" BPC=");
800 print_address (read_register (BPC_REGNUM), gdb_stdout);
801
802 printf_filtered (" BPSW=");
803 d30v_print_register (BPSW_REGNUM, 1);
804 printf_filtered ("\n");
805
806 printf_filtered ("DPC=");
807 print_address (read_register (DPC_REGNUM), gdb_stdout);
808
809 printf_filtered (" DPSW=");
810 d30v_print_register (DPSW_REGNUM, 1);
811
812 printf_filtered (" IBA=");
813 print_address (read_register (IBA_REGNUM), gdb_stdout);
814 printf_filtered ("\n");
815
816 printf_filtered ("RPT_C=");
817 d30v_print_register (RPT_C_REGNUM, 1);
818
819 printf_filtered (" RPT_S=");
820 print_address (read_register (RPT_S_REGNUM), gdb_stdout);
821
822 printf_filtered (" RPT_E=");
823 print_address (read_register (RPT_E_REGNUM), gdb_stdout);
824 printf_filtered ("\n");
825
826 printf_filtered ("MOD_S=");
827 print_address (read_register (MOD_S_REGNUM), gdb_stdout);
828
829 printf_filtered (" MOD_E=");
830 print_address (read_register (MOD_E_REGNUM), gdb_stdout);
831 printf_filtered ("\n");
832
833 printf_filtered ("EIT_VB=");
834 print_address (read_register (EIT_VB_REGNUM), gdb_stdout);
835
836 printf_filtered (" INT_S=");
837 d30v_print_register (INT_S_REGNUM, 1);
838
839 printf_filtered (" INT_M=");
840 d30v_print_register (INT_M_REGNUM, 1);
841 printf_filtered ("\n");
842
5d62f957 843 d30v_print_flags ();
45a70ed6
SG
844 for (regnum = 0; regnum <= 63;)
845 {
846 int i;
847
848 printf_filtered ("R%d-R%d ", regnum, regnum + 7);
849 if (regnum < 10)
850 printf_filtered (" ");
851 if (regnum + 7 < 10)
852 printf_filtered (" ");
853
854 for (i = 0; i < 8; i++)
855 {
856 printf_filtered (" ");
857 d30v_print_register (regnum++, 1);
858 }
859
860 printf_filtered ("\n");
861 }
862
863 printf_filtered ("A0-A1 ");
864
865 d30v_print_register (A0_REGNUM, 1);
866 printf_filtered (" ");
867 d30v_print_register (A1_REGNUM, 1);
868 printf_filtered ("\n");
869}
870
871CORE_ADDR
872d30v_fix_call_dummy (dummyname, start_sp, fun, nargs, args, type, gcc_p)
873 char *dummyname;
874 CORE_ADDR start_sp;
875 CORE_ADDR fun;
876 int nargs;
877 value_ptr *args;
878 struct type *type;
879 int gcc_p;
880{
881 int regnum;
882 CORE_ADDR sp;
883 char buffer[MAX_REGISTER_RAW_SIZE];
884 struct frame_info *frame = get_current_frame ();
885 frame->dummy = start_sp;
7359fb1d 886 /*start_sp |= DMEM_START;*/
45a70ed6
SG
887
888 sp = start_sp;
889 for (regnum = 0; regnum < NUM_REGS; regnum++)
890 {
891 sp -= REGISTER_RAW_SIZE(regnum);
892 store_address (buffer, REGISTER_RAW_SIZE(regnum), read_register(regnum));
893 write_memory (sp, buffer, REGISTER_RAW_SIZE(regnum));
894 }
7359fb1d 895 write_register (SP_REGNUM, (LONGEST)sp);
45a70ed6 896 /* now we need to load LR with the return address */
7359fb1d 897 write_register (LR_REGNUM, (LONGEST)d30v_call_dummy_address());
45a70ed6
SG
898 return sp;
899}
900
901static void
902d30v_pop_dummy_frame (fi)
903 struct frame_info *fi;
904{
905 CORE_ADDR sp = fi->dummy;
906 int regnum;
907
908 for (regnum = 0; regnum < NUM_REGS; regnum++)
909 {
910 sp -= REGISTER_RAW_SIZE(regnum);
911 write_register(regnum, read_memory_unsigned_integer (sp, REGISTER_RAW_SIZE(regnum)));
912 }
913 flush_cached_frames (); /* needed? */
914}
915
916
917CORE_ADDR
918d30v_push_arguments (nargs, args, sp, struct_return, struct_addr)
919 int nargs;
920 value_ptr *args;
921 CORE_ADDR sp;
922 int struct_return;
923 CORE_ADDR struct_addr;
924{
925 int i, len, index=0, regnum=2;
926 char buffer[4], *contents;
927 LONGEST val;
928 CORE_ADDR ptrs[10];
929
7359fb1d 930#if 0
45a70ed6
SG
931 /* Pass 1. Put all large args on stack */
932 for (i = 0; i < nargs; i++)
933 {
934 value_ptr arg = args[i];
935 struct type *arg_type = check_typedef (VALUE_TYPE (arg));
936 len = TYPE_LENGTH (arg_type);
937 contents = VALUE_CONTENTS(arg);
938 val = extract_signed_integer (contents, len);
939 if (len > 4)
940 {
941 /* put on stack and pass pointers */
942 sp -= len;
943 write_memory (sp, contents, len);
944 ptrs[index++] = sp;
945 }
946 }
7359fb1d 947#endif
45a70ed6
SG
948 index = 0;
949
950 for (i = 0; i < nargs; i++)
951 {
952 value_ptr arg = args[i];
953 struct type *arg_type = check_typedef (VALUE_TYPE (arg));
954 len = TYPE_LENGTH (arg_type);
955 contents = VALUE_CONTENTS(arg);
45a70ed6
SG
956 if (len > 4)
957 {
7359fb1d
DT
958 /* we need multiple registers */
959 int ndx;
960
7ae2b433 961 for (ndx = 0; len > 0; ndx += 8, len -= 8)
45a70ed6 962 {
7ae2b433
DT
963 if (regnum & 1)
964 regnum++; /* all args > 4 bytes start in even register */
965
7359fb1d
DT
966 if (regnum < 18)
967 {
7ae2b433
DT
968 val = extract_signed_integer (&contents[ndx], 4);
969 write_register (regnum++, val);
7359fb1d 970
7ae2b433
DT
971 if (len >= 8)
972 val = extract_signed_integer (&contents[ndx+4], 4);
973 else
974 val = extract_signed_integer (&contents[ndx+4], len-4);
7359fb1d
DT
975 write_register (regnum++, val);
976 }
977 else
978 {
979 /* no more registers available. put it on the stack */
7ae2b433
DT
980
981 /* all args > 4 bytes are padded to a multiple of 8 bytes
982 and start on an 8 byte boundary */
983 if (sp & 7)
984 sp -= (sp & 7); /* align it */
985
986 sp -= ((len + 7) & ~7); /* allocate space */
7359fb1d
DT
987 write_memory (sp, &contents[ndx], len);
988 break;
989 }
45a70ed6
SG
990 }
991 }
992 else
993 {
7359fb1d 994 if (regnum < 18 )
45a70ed6 995 {
7ae2b433 996 val = extract_signed_integer (contents, len);
7359fb1d 997 write_register (regnum++, val);
45a70ed6
SG
998 }
999 else
1000 {
7ae2b433
DT
1001 /* all args are padded to a multiple of 4 bytes (at least) */
1002 sp -= ((len + 3) & ~3);
1003 write_memory (sp, contents, len);
45a70ed6
SG
1004 }
1005 }
1006 }
7ae2b433
DT
1007 if (sp & 7)
1008 /* stack pointer is not on an 8 byte boundary -- align it */
1009 sp -= (sp & 7);
45a70ed6
SG
1010 return sp;
1011}
1012
1013
1014/* pick an out-of-the-way place to set the return value */
1015/* for an inferior function call. The link register is set to this */
1016/* value and a momentary breakpoint is set there. When the breakpoint */
1017/* is hit, the dummy frame is popped and the previous environment is */
1018/* restored. */
1019
1020CORE_ADDR
1021d30v_call_dummy_address ()
1022{
1023 CORE_ADDR entry;
1024 struct minimal_symbol *sym;
1025
1026 entry = entry_point_address ();
1027
1028 if (entry != 0)
1029 return entry;
1030
1031 sym = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
1032
1033 if (!sym || MSYMBOL_TYPE (sym) != mst_text)
1034 return 0;
1035 else
1036 return SYMBOL_VALUE_ADDRESS (sym);
1037}
1038
1039/* Given a return value in `regbuf' with a type `valtype',
1040 extract and copy its value into `valbuf'. */
1041
1042void
1043d30v_extract_return_value (valtype, regbuf, valbuf)
1044 struct type *valtype;
1045 char regbuf[REGISTER_BYTES];
1046 char *valbuf;
1047{
1048 memcpy (valbuf, regbuf + REGISTER_BYTE (2), TYPE_LENGTH (valtype));
1049}
1050
1051/* The following code implements access to, and display of, the D30V's
1052 instruction trace buffer. The buffer consists of 64K or more
1053 4-byte words of data, of which each words includes an 8-bit count,
1054 an 8-bit segment number, and a 16-bit instruction address.
1055
1056 In theory, the trace buffer is continuously capturing instruction
1057 data that the CPU presents on its "debug bus", but in practice, the
1058 ROMified GDB stub only enables tracing when it continues or steps
1059 the program, and stops tracing when the program stops; so it
1060 actually works for GDB to read the buffer counter out of memory and
1061 then read each trace word. The counter records where the tracing
1062 stops, but there is no record of where it started, so we remember
1063 the PC when we resumed and then search backwards in the trace
1064 buffer for a word that includes that address. This is not perfect,
1065 because you will miss trace data if the resumption PC is the target
1066 of a branch. (The value of the buffer counter is semi-random, any
1067 trace data from a previous program stop is gone.) */
1068
1069/* The address of the last word recorded in the trace buffer. */
1070
1071#define DBBC_ADDR (0xd80000)
1072
1073/* The base of the trace buffer, at least for the "Board_0". */
1074
1075#define TRACE_BUFFER_BASE (0xf40000)
1076
1077static void trace_command PARAMS ((char *, int));
1078
1079static void untrace_command PARAMS ((char *, int));
1080
1081static void trace_info PARAMS ((char *, int));
1082
1083static void tdisassemble_command PARAMS ((char *, int));
1084
1085static void display_trace PARAMS ((int, int));
1086
1087/* True when instruction traces are being collected. */
1088
1089static int tracing;
1090
1091/* Remembered PC. */
1092
1093static CORE_ADDR last_pc;
1094
1095/* True when trace output should be displayed whenever program stops. */
1096
1097static int trace_display;
1098
1099/* True when trace listing should include source lines. */
1100
1101static int default_trace_show_source = 1;
1102
1103struct trace_buffer {
1104 int size;
1105 short *counts;
1106 CORE_ADDR *addrs;
1107} trace_data;
1108
1109static void
1110trace_command (args, from_tty)
1111 char *args;
1112 int from_tty;
1113{
1114 /* Clear the host-side trace buffer, allocating space if needed. */
1115 trace_data.size = 0;
1116 if (trace_data.counts == NULL)
1117 trace_data.counts = (short *) xmalloc (65536 * sizeof(short));
1118 if (trace_data.addrs == NULL)
1119 trace_data.addrs = (CORE_ADDR *) xmalloc (65536 * sizeof(CORE_ADDR));
1120
1121 tracing = 1;
1122
1123 printf_filtered ("Tracing is now on.\n");
1124}
1125
1126static void
1127untrace_command (args, from_tty)
1128 char *args;
1129 int from_tty;
1130{
1131 tracing = 0;
1132
1133 printf_filtered ("Tracing is now off.\n");
1134}
1135
1136static void
1137trace_info (args, from_tty)
1138 char *args;
1139 int from_tty;
1140{
1141 int i;
1142
1143 if (trace_data.size)
1144 {
1145 printf_filtered ("%d entries in trace buffer:\n", trace_data.size);
1146
1147 for (i = 0; i < trace_data.size; ++i)
1148 {
1149 printf_filtered ("%d: %d instruction%s at 0x%x\n",
1150 i, trace_data.counts[i],
1151 (trace_data.counts[i] == 1 ? "" : "s"),
1152 trace_data.addrs[i]);
1153 }
1154 }
1155 else
1156 printf_filtered ("No entries in trace buffer.\n");
1157
1158 printf_filtered ("Tracing is currently %s.\n", (tracing ? "on" : "off"));
1159}
1160
1161/* Print the instruction at address MEMADDR in debugged memory,
1162 on STREAM. Returns length of the instruction, in bytes. */
1163
1164static int
1165print_insn (memaddr, stream)
1166 CORE_ADDR memaddr;
1167 GDB_FILE *stream;
1168{
1169 /* If there's no disassembler, something is very wrong. */
1170 if (tm_print_insn == NULL)
1171 abort ();
1172
1173 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
1174 tm_print_insn_info.endian = BFD_ENDIAN_BIG;
1175 else
1176 tm_print_insn_info.endian = BFD_ENDIAN_LITTLE;
1177 return (*tm_print_insn) (memaddr, &tm_print_insn_info);
1178}
1179
1180void
1181d30v_eva_prepare_to_trace ()
1182{
1183 if (!tracing)
1184 return;
1185
1186 last_pc = read_register (PC_REGNUM);
1187}
1188
1189/* Collect trace data from the target board and format it into a form
1190 more useful for display. */
1191
1192void
1193d30v_eva_get_trace_data ()
1194{
1195 int count, i, j, oldsize;
1196 int trace_addr, trace_seg, trace_cnt, next_cnt;
1197 unsigned int last_trace, trace_word, next_word;
1198 unsigned int *tmpspace;
1199
1200 if (!tracing)
1201 return;
1202
1203 tmpspace = xmalloc (65536 * sizeof(unsigned int));
1204
1205 last_trace = read_memory_unsigned_integer (DBBC_ADDR, 2) << 2;
1206
1207 /* Collect buffer contents from the target, stopping when we reach
1208 the word recorded when execution resumed. */
1209
1210 count = 0;
1211 while (last_trace > 0)
1212 {
1213 QUIT;
1214 trace_word =
1215 read_memory_unsigned_integer (TRACE_BUFFER_BASE + last_trace, 4);
1216 trace_addr = trace_word & 0xffff;
1217 last_trace -= 4;
1218 /* Ignore an apparently nonsensical entry. */
1219 if (trace_addr == 0xffd5)
1220 continue;
1221 tmpspace[count++] = trace_word;
1222 if (trace_addr == last_pc)
1223 break;
1224 if (count > 65535)
1225 break;
1226 }
1227
1228 /* Move the data to the host-side trace buffer, adjusting counts to
1229 include the last instruction executed and transforming the address
1230 into something that GDB likes. */
1231
1232 for (i = 0; i < count; ++i)
1233 {
1234 trace_word = tmpspace[i];
1235 next_word = ((i == 0) ? 0 : tmpspace[i - 1]);
1236 trace_addr = trace_word & 0xffff;
1237 next_cnt = (next_word >> 24) & 0xff;
1238 j = trace_data.size + count - i - 1;
1239 trace_data.addrs[j] = (trace_addr << 2) + 0x1000000;
1240 trace_data.counts[j] = next_cnt + 1;
1241 }
1242
1243 oldsize = trace_data.size;
1244 trace_data.size += count;
1245
1246 free (tmpspace);
1247
1248 if (trace_display)
1249 display_trace (oldsize, trace_data.size);
1250}
1251
1252static void
1253tdisassemble_command (arg, from_tty)
1254 char *arg;
1255 int from_tty;
1256{
1257 int i, count;
1258 CORE_ADDR low, high;
1259 char *space_index;
1260
1261 if (!arg)
1262 {
1263 low = 0;
1264 high = trace_data.size;
1265 }
1266 else if (!(space_index = (char *) strchr (arg, ' ')))
1267 {
1268 low = parse_and_eval_address (arg);
1269 high = low + 5;
1270 }
1271 else
1272 {
1273 /* Two arguments. */
1274 *space_index = '\0';
1275 low = parse_and_eval_address (arg);
1276 high = parse_and_eval_address (space_index + 1);
1277 if (high < low)
1278 high = low;
1279 }
1280
1281 printf_filtered ("Dump of trace from %d to %d:\n", low, high);
1282
1283 display_trace (low, high);
1284
1285 printf_filtered ("End of trace dump.\n");
1286 gdb_flush (gdb_stdout);
1287}
1288
1289static void
1290display_trace (low, high)
1291 int low, high;
1292{
1293 int i, count, trace_show_source, first, suppress;
1294 CORE_ADDR next_address;
1295
1296 trace_show_source = default_trace_show_source;
1297 if (!have_full_symbols () && !have_partial_symbols())
1298 {
1299 trace_show_source = 0;
1300 printf_filtered ("No symbol table is loaded. Use the \"file\" command.\n");
1301 printf_filtered ("Trace will not display any source.\n");
1302 }
1303
1304 first = 1;
1305 suppress = 0;
1306 for (i = low; i < high; ++i)
1307 {
1308 next_address = trace_data.addrs[i];
1309 count = trace_data.counts[i];
1310 while (count-- > 0)
1311 {
1312 QUIT;
1313 if (trace_show_source)
1314 {
1315 struct symtab_and_line sal, sal_prev;
1316
1317 sal_prev = find_pc_line (next_address - 4, 0);
1318 sal = find_pc_line (next_address, 0);
1319
1320 if (sal.symtab)
1321 {
1322 if (first || sal.line != sal_prev.line)
1323 print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
1324 suppress = 0;
1325 }
1326 else
1327 {
1328 if (!suppress)
1329 /* FIXME-32x64--assumes sal.pc fits in long. */
1330 printf_filtered ("No source file for address %s.\n",
1331 local_hex_string((unsigned long) sal.pc));
1332 suppress = 1;
1333 }
1334 }
1335 first = 0;
1336 print_address (next_address, gdb_stdout);
1337 printf_filtered (":");
1338 printf_filtered ("\t");
1339 wrap_here (" ");
1340 next_address = next_address + print_insn (next_address, gdb_stdout);
1341 printf_filtered ("\n");
1342 gdb_flush (gdb_stdout);
1343 }
1344 }
1345}
1346
1347extern void (*target_resume_hook) PARAMS ((void));
1348extern void (*target_wait_loop_hook) PARAMS ((void));
1349
1350void
1351_initialize_d30v_tdep ()
1352{
1353 tm_print_insn = print_insn_d30v;
1354
1355 target_resume_hook = d30v_eva_prepare_to_trace;
1356 target_wait_loop_hook = d30v_eva_get_trace_data;
1357
5d62f957
MM
1358 add_info ("flags", print_flags_command, "Print d30v flags.");
1359
45a70ed6
SG
1360 add_com ("trace", class_support, trace_command,
1361 "Enable tracing of instruction execution.");
1362
1363 add_com ("untrace", class_support, untrace_command,
7359fb1d 1364 "Disable tracing of instruction execution.");
45a70ed6
SG
1365
1366 add_com ("tdisassemble", class_vars, tdisassemble_command,
1367 "Disassemble the trace buffer.\n\
1368Two optional arguments specify a range of trace buffer entries\n\
1369as reported by info trace (NOT addresses!).");
1370
1371 add_info ("trace", trace_info,
1372 "Display info about the trace data buffer.");
1373
1374 add_show_from_set (add_set_cmd ("tracedisplay", no_class,
1375 var_integer, (char *)&trace_display,
1376 "Set automatic display of trace.\n", &setlist),
1377 &showlist);
1378 add_show_from_set (add_set_cmd ("tracesource", no_class,
1379 var_integer, (char *)&default_trace_show_source,
1380 "Set display of source code with trace.\n", &setlist),
1381 &showlist);
1382
1383}
This page took 0.093566 seconds and 4 git commands to generate.