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