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