]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/vax-tdep.c
2002-04-18 Michael Snyder <msnyder@redhat.com>
[thirdparty/binutils-gdb.git] / gdb / vax-tdep.c
CommitLineData
c906108c 1/* Print VAX instructions for GDB, the GNU debugger.
51eb8b08 2 Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000, 2002
b6ba6518 3 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
c906108c 11
c5aa993b
JM
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
c906108c 16
c5aa993b
JM
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c
SS
21
22#include "defs.h"
23#include "symtab.h"
24#include "opcode/vax.h"
c11c3a98
AC
25#include "gdbcore.h"
26#include "frame.h"
27#include "value.h"
c906108c 28
75bc7ddf
AC
29/* Return 1 if P points to an invalid floating point value.
30 LEN is the length in bytes -- not relevant on the Vax. */
31
32/* FIXME: cagney/2002-01-19: The macro below was originally defined in
33 tm-vax.h and used in values.c. Two problems. Firstly this is a
34 very non-portable and secondly it is wrong. The VAX should be
35 using floatformat and associated methods to identify and handle
36 invalid floating-point values. Adding to the poor target's woes
37 there is no floatformat_vax_{f,d} and no TARGET_FLOAT_FORMAT
38 et.al.. */
39
40/* FIXME: cagney/2002-01-19: It turns out that the only thing that
41 uses this macro is the vax disassembler code (so how old is this
42 target?). This target should instead be using the opcodes
43 disassembler. That allowing the macro to be eliminated. */
44
45#define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)
46
c906108c
SS
47/* Vax instructions are never longer than this. */
48#define MAXLEN 62
49
50/* Number of elements in the opcode table. */
51#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
52
53static unsigned char *print_insn_arg ();
54\f
51eb8b08
JT
55char *
56vax_register_name (int regno)
57{
58 static char *register_names[] =
59 {
60 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
61 "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
62 "ps",
63 };
64
65 if (regno < 0)
66 return (NULL);
67 if (regno >= (sizeof(register_names) / sizeof(*register_names)))
68 return (NULL);
69 return (register_names[regno]);
70}
71
72int
73vax_register_byte (int regno)
74{
75 return (regno * 4);
76}
77
78int
79vax_register_raw_size (int regno)
80{
81 return (4);
82}
83
84int
85vax_register_virtual_size (int regno)
86{
87 return (4);
88}
89
90struct type *
91vax_register_virtual_type (int regno)
92{
93 return (builtin_type_int);
94}
95\f
ab62c900
JT
96void
97vax_frame_init_saved_regs (struct frame_info *frame)
98{
99 int regnum, regmask;
100 CORE_ADDR next_addr;
101
102 if (frame->saved_regs)
103 return;
104
105 frame_saved_regs_zalloc (frame);
106
107 regmask = read_memory_integer (frame->frame + 4, 4) >> 16;
108
109 next_addr = frame->frame + 16;
110
111 /* regmask's low bit is for register 0, which is the first one
112 what would be pushed. */
113 for (regnum = 0; regnum < AP_REGNUM; regnum++)
114 {
115 if (regmask & (1 << regnum))
116 frame->saved_regs[regnum] = next_addr += 4;
117 }
118
119 frame->saved_regs[SP_REGNUM] = next_addr + 4;
120 if (regmask & (1 << FP_REGNUM))
121 frame->saved_regs[SP_REGNUM] +=
122 4 + (4 * read_memory_integer (next_addr + 4, 4));
123
124 frame->saved_regs[PC_REGNUM] = frame->frame + 16;
125 frame->saved_regs[FP_REGNUM] = frame->frame + 12;
126 frame->saved_regs[AP_REGNUM] = frame->frame + 8;
127 frame->saved_regs[PS_REGNUM] = frame->frame + 4;
128}
5516aa92
JT
129
130CORE_ADDR
131vax_frame_saved_pc (struct frame_info *frame)
132{
133 if (frame->signal_handler_caller)
134 return (sigtramp_saved_pc (frame)); /* XXXJRT */
135
136 return (read_memory_integer (frame->frame + 16, 4));
137}
138
139CORE_ADDR
140vax_frame_args_address_correct (struct frame_info *frame)
141{
142 /* Cannot find the AP register value directly from the FP value. Must
143 find it saved in the frame called by this one, or in the AP register
144 for the innermost frame. However, there is no way to tell the
145 difference between the innermost frame and a frame for which we
146 just don't know the frame that it called (e.g. "info frame 0x7ffec789").
147 For the sake of argument, suppose that the stack is somewhat trashed
148 (which is one reason that "info frame" exists). So, return 0 (indicating
149 we don't know the address of the arglist) if we don't know what frame
150 this frame calls. */
151 if (frame->next)
152 return (read_memory_integer (frame->next->frame + 8, 4));
153
154 return (0);
155}
156
157CORE_ADDR
158vax_frame_args_address (struct frame_info *frame)
159{
160 /* In most of GDB, getting the args address is too important to
161 just say "I don't know". This is sometimes wrong for functions
162 that aren't on top of the stack, but c'est la vie. */
163 if (frame->next)
164 return (read_memory_integer (frame->next->frame + 8, 4));
165
166 return (read_register (AP_REGNUM));
167}
168
169CORE_ADDR
170vax_frame_locals_address (struct frame_info *frame)
171{
172 return (frame->frame);
173}
174
175int
176vax_frame_num_args (struct frame_info *fi)
177{
178 return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
179}
52efde73
JT
180
181CORE_ADDR
182vax_frame_chain (struct frame_info *frame)
183{
184 /* In the case of the VAX, the frame's nominal address is the FP value,
185 and 12 bytes later comes the saved previous FP value as a 4-byte word. */
186 if (inside_entry_file (frame->pc))
187 return (0);
188
189 return (read_memory_integer (frame->frame + 12, 4));
190}
191\f
192void
193vax_push_dummy_frame (void)
194{
195 CORE_ADDR sp = read_register (SP_REGNUM);
196 int regnum;
197
198 sp = push_word (sp, 0); /* arglist */
199 for (regnum = 11; regnum >= 0; regnum--)
200 sp = push_word (sp, read_register (regnum));
201 sp = push_word (sp, read_register (PC_REGNUM));
202 sp = push_word (sp, read_register (FP_REGNUM));
203 sp = push_word (sp, read_register (AP_REGNUM));
204 sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) + 0x2fff0000);
205 sp = push_word (sp, 0);
206 write_register (SP_REGNUM, sp);
207 write_register (FP_REGNUM, sp);
208 write_register (AP_REGNUM, sp + (17 * 4));
209}
210
211void
212vax_pop_frame (void)
213{
214 CORE_ADDR fp = read_register (FP_REGNUM);
215 int regnum;
216 int regmask = read_memory_integer (fp + 4, 4);
217
218 write_register (PS_REGNUM,
219 (regmask & 0xffff)
220 | (read_register (PS_REGNUM) & 0xffff0000));
221 write_register (PC_REGNUM, read_memory_integer (fp + 16, 4));
222 write_register (FP_REGNUM, read_memory_integer (fp + 12, 4));
223 write_register (AP_REGNUM, read_memory_integer (fp + 8, 4));
224 fp += 16;
225 for (regnum = 0; regnum < 12; regnum++)
226 if (regmask & (0x10000 << regnum))
227 write_register (regnum, read_memory_integer (fp += 4, 4));
228 fp = fp + 4 + ((regmask >> 30) & 3);
229 if (regmask & 0x20000000)
230 {
231 regnum = read_memory_integer (fp, 4);
232 fp += (regnum + 1) * 4;
233 }
234 write_register (SP_REGNUM, fp);
235 flush_cached_frames ();
236}
ab62c900 237\f
ea74468c
JT
238void
239vax_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
240{
241 write_register (1, addr);
242}
243
244void
245vax_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
246{
247 memcpy (valbuf, regbuf + REGISTER_BYTE (0), TYPE_LENGTH (valtype));
248}
249
250void
251vax_store_return_value (struct type *valtype, char *valbuf)
252{
253 write_register_bytes (0, valbuf, TYPE_LENGTH (valtype));
254}
255
256CORE_ADDR
257vax_extract_struct_value_address (char *regbuf)
258{
259 return (extract_address (regbuf + REGISTER_BYTE (0), REGISTER_RAW_SIZE (0)));
260}
261\f
b83266a0
SS
262/* Advance PC across any function entry prologue instructions
263 to reach some "real" code. */
264
265CORE_ADDR
fba45db2 266vax_skip_prologue (CORE_ADDR pc)
b83266a0
SS
267{
268 register int op = (unsigned char) read_memory_integer (pc, 1);
269 if (op == 0x11)
c5aa993b 270 pc += 2; /* skip brb */
b83266a0 271 if (op == 0x31)
c5aa993b 272 pc += 3; /* skip brw */
b83266a0 273 if (op == 0xC2
c5aa993b
JM
274 && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
275 pc += 3; /* skip subl2 */
b83266a0 276 if (op == 0x9E
c5aa993b
JM
277 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
278 && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
279 pc += 4; /* skip movab */
b83266a0 280 if (op == 0x9E
c5aa993b
JM
281 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
282 && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
283 pc += 5; /* skip movab */
b83266a0 284 if (op == 0x9E
c5aa993b
JM
285 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
286 && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
287 pc += 7; /* skip movab */
b83266a0
SS
288 return pc;
289}
290
392a587b 291
c906108c
SS
292/* Print the vax instruction at address MEMADDR in debugged memory,
293 from disassembler info INFO.
294 Returns length of the instruction, in bytes. */
295
296static int
fba45db2 297vax_print_insn (CORE_ADDR memaddr, disassemble_info *info)
c906108c
SS
298{
299 unsigned char buffer[MAXLEN];
300 register int i;
301 register unsigned char *p;
c11c3a98 302 const char *d;
c906108c
SS
303
304 int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
305 if (status != 0)
306 {
307 (*info->memory_error_func) (status, memaddr, info);
308 return -1;
309 }
310
311 for (i = 0; i < NOPCODES; i++)
312 if (votstrs[i].detail.code == buffer[0]
c5aa993b 313 || votstrs[i].detail.code == *(unsigned short *) buffer)
c906108c
SS
314 break;
315
316 /* Handle undefined instructions. */
317 if (i == NOPCODES)
318 {
319 (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
320 return 1;
321 }
322
323 (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
324
325 /* Point at first byte of argument data,
326 and at descriptor for first argument. */
327 p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
328 d = votstrs[i].detail.args;
329
330 if (*d)
331 (*info->fprintf_func) (info->stream, " ");
332
333 while (*d)
334 {
335 p = print_insn_arg (d, p, memaddr + (p - buffer), info);
336 d += 2;
337 if (*d)
338 (*info->fprintf_func) (info->stream, ",");
339 }
340 return p - buffer;
341}
342
343static unsigned char *
fba45db2
KB
344print_insn_arg (char *d, register char *p, CORE_ADDR addr,
345 disassemble_info *info)
c906108c
SS
346{
347 register int regnum = *p & 0xf;
348 float floatlitbuf;
349
350 if (*d == 'b')
351 {
352 if (d[1] == 'b')
353 (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
354 else
355 {
c5aa993b 356 (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
c906108c
SS
357 p += 2;
358 }
359 }
360 else
361 switch ((*p++ >> 4) & 0xf)
362 {
363 case 0:
364 case 1:
365 case 2:
366 case 3: /* Literal mode */
367 if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
368 {
c5aa993b 369 *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
c906108c
SS
370 (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
371 }
372 else
373 (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
374 break;
375
376 case 4: /* Indexed */
377 p = (char *) print_insn_arg (d, p, addr + 1, info);
378 (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
379 break;
380
381 case 5: /* Register */
382 (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
383 break;
384
385 case 7: /* Autodecrement */
386 (*info->fprintf_func) (info->stream, "-");
387 case 6: /* Register deferred */
388 (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
389 break;
390
391 case 9: /* Autoincrement deferred */
392 (*info->fprintf_func) (info->stream, "@");
393 if (regnum == PC_REGNUM)
394 {
395 (*info->fprintf_func) (info->stream, "#");
c5aa993b 396 info->target = *(long *) p;
c906108c
SS
397 (*info->print_address_func) (info->target, info);
398 p += 4;
399 break;
400 }
401 case 8: /* Autoincrement */
402 if (regnum == PC_REGNUM)
403 {
404 (*info->fprintf_func) (info->stream, "#");
405 switch (d[1])
406 {
407 case 'b':
408 (*info->fprintf_func) (info->stream, "%d", *p++);
409 break;
410
411 case 'w':
c5aa993b 412 (*info->fprintf_func) (info->stream, "%d", *(short *) p);
c906108c
SS
413 p += 2;
414 break;
415
416 case 'l':
c5aa993b 417 (*info->fprintf_func) (info->stream, "%d", *(long *) p);
c906108c
SS
418 p += 4;
419 break;
420
421 case 'q':
422 (*info->fprintf_func) (info->stream, "0x%x%08x",
c5aa993b 423 ((long *) p)[1], ((long *) p)[0]);
c906108c
SS
424 p += 8;
425 break;
426
427 case 'o':
428 (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
c5aa993b
JM
429 ((long *) p)[3], ((long *) p)[2],
430 ((long *) p)[1], ((long *) p)[0]);
c906108c
SS
431 p += 16;
432 break;
433
434 case 'f':
435 if (INVALID_FLOAT (p, 4))
436 (*info->fprintf_func) (info->stream,
437 "<<invalid float 0x%x>>",
438 *(int *) p);
439 else
440 (*info->fprintf_func) (info->stream, "%f", *(float *) p);
441 p += 4;
442 break;
443
444 case 'd':
445 if (INVALID_FLOAT (p, 8))
446 (*info->fprintf_func) (info->stream,
447 "<<invalid float 0x%x%08x>>",
c5aa993b 448 ((long *) p)[1], ((long *) p)[0]);
c906108c
SS
449 else
450 (*info->fprintf_func) (info->stream, "%f", *(double *) p);
451 p += 8;
452 break;
453
454 case 'g':
455 (*info->fprintf_func) (info->stream, "g-float");
456 p += 8;
457 break;
458
459 case 'h':
460 (*info->fprintf_func) (info->stream, "h-float");
461 p += 16;
462 break;
463
464 }
465 }
466 else
467 (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
468 break;
469
470 case 11: /* Byte displacement deferred */
471 (*info->fprintf_func) (info->stream, "@");
472 case 10: /* Byte displacement */
473 if (regnum == PC_REGNUM)
474 {
475 info->target = addr + *p + 2;
476 (*info->print_address_func) (info->target, info);
477 }
478 else
479 (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
480 p += 1;
481 break;
482
483 case 13: /* Word displacement deferred */
484 (*info->fprintf_func) (info->stream, "@");
485 case 12: /* Word displacement */
486 if (regnum == PC_REGNUM)
487 {
c5aa993b 488 info->target = addr + *(short *) p + 3;
c906108c
SS
489 (*info->print_address_func) (info->target, info);
490 }
491 else
492 (*info->fprintf_func) (info->stream, "%d(%s)",
c5aa993b 493 *(short *) p, REGISTER_NAME (regnum));
c906108c
SS
494 p += 2;
495 break;
496
497 case 15: /* Long displacement deferred */
498 (*info->fprintf_func) (info->stream, "@");
499 case 14: /* Long displacement */
500 if (regnum == PC_REGNUM)
501 {
c5aa993b 502 info->target = addr + *(short *) p + 5;
c906108c
SS
503 (*info->print_address_func) (info->target, info);
504 }
505 else
506 (*info->fprintf_func) (info->stream, "%d(%s)",
c5aa993b 507 *(long *) p, REGISTER_NAME (regnum));
c906108c
SS
508 p += 4;
509 }
510
511 return (unsigned char *) p;
512}
513
514void
fba45db2 515_initialize_vax_tdep (void)
c906108c
SS
516{
517 tm_print_insn = vax_print_insn;
518}