OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [vax-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Print VAX instructions for GDB, the GNU debugger.
2
   Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
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.
11
 
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.
16
 
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.  */
21
 
22
#include "defs.h"
23
#include "symtab.h"
24
#include "opcode/vax.h"
25
#include "gdbcore.h"
26
#include "frame.h"
27
#include "value.h"
28
 
29
/* Vax instructions are never longer than this.  */
30
#define MAXLEN 62
31
 
32
/* Number of elements in the opcode table.  */
33
#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
34
 
35
static unsigned char *print_insn_arg ();
36
 
37
/* Advance PC across any function entry prologue instructions
38
   to reach some "real" code.  */
39
 
40
CORE_ADDR
41
vax_skip_prologue (CORE_ADDR pc)
42
{
43
  register int op = (unsigned char) read_memory_integer (pc, 1);
44
  if (op == 0x11)
45
    pc += 2;                    /* skip brb */
46
  if (op == 0x31)
47
    pc += 3;                    /* skip brw */
48
  if (op == 0xC2
49
      && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
50
    pc += 3;                    /* skip subl2 */
51
  if (op == 0x9E
52
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
53
      && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
54
    pc += 4;                    /* skip movab */
55
  if (op == 0x9E
56
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
57
      && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
58
    pc += 5;                    /* skip movab */
59
  if (op == 0x9E
60
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
61
      && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
62
    pc += 7;                    /* skip movab */
63
  return pc;
64
}
65
 
66
/* Return number of args passed to a frame.
67
   Can return -1, meaning no way to tell.  */
68
 
69
int
70
vax_frame_num_args (struct frame_info *fi)
71
{
72
  return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
73
}
74
 
75
 
76
 
77
/* Print the vax instruction at address MEMADDR in debugged memory,
78
   from disassembler info INFO.
79
   Returns length of the instruction, in bytes.  */
80
 
81
static int
82
vax_print_insn (CORE_ADDR memaddr, disassemble_info *info)
83
{
84
  unsigned char buffer[MAXLEN];
85
  register int i;
86
  register unsigned char *p;
87
  const char *d;
88
 
89
  int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
90
  if (status != 0)
91
    {
92
      (*info->memory_error_func) (status, memaddr, info);
93
      return -1;
94
    }
95
 
96
  for (i = 0; i < NOPCODES; i++)
97
    if (votstrs[i].detail.code == buffer[0]
98
        || votstrs[i].detail.code == *(unsigned short *) buffer)
99
      break;
100
 
101
  /* Handle undefined instructions.  */
102
  if (i == NOPCODES)
103
    {
104
      (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
105
      return 1;
106
    }
107
 
108
  (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
109
 
110
  /* Point at first byte of argument data,
111
     and at descriptor for first argument.  */
112
  p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
113
  d = votstrs[i].detail.args;
114
 
115
  if (*d)
116
    (*info->fprintf_func) (info->stream, " ");
117
 
118
  while (*d)
119
    {
120
      p = print_insn_arg (d, p, memaddr + (p - buffer), info);
121
      d += 2;
122
      if (*d)
123
        (*info->fprintf_func) (info->stream, ",");
124
    }
125
  return p - buffer;
126
}
127
 
128
static unsigned char *
129
print_insn_arg (char *d, register char *p, CORE_ADDR addr,
130
                disassemble_info *info)
131
{
132
  register int regnum = *p & 0xf;
133
  float floatlitbuf;
134
 
135
  if (*d == 'b')
136
    {
137
      if (d[1] == 'b')
138
        (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
139
      else
140
        {
141
          (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
142
          p += 2;
143
        }
144
    }
145
  else
146
    switch ((*p++ >> 4) & 0xf)
147
      {
148
      case 0:
149
      case 1:
150
      case 2:
151
      case 3:                   /* Literal mode */
152
        if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
153
          {
154
            *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
155
            (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
156
          }
157
        else
158
          (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
159
        break;
160
 
161
      case 4:                   /* Indexed */
162
        p = (char *) print_insn_arg (d, p, addr + 1, info);
163
        (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
164
        break;
165
 
166
      case 5:                   /* Register */
167
        (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
168
        break;
169
 
170
      case 7:                   /* Autodecrement */
171
        (*info->fprintf_func) (info->stream, "-");
172
      case 6:                   /* Register deferred */
173
        (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
174
        break;
175
 
176
      case 9:                   /* Autoincrement deferred */
177
        (*info->fprintf_func) (info->stream, "@");
178
        if (regnum == PC_REGNUM)
179
          {
180
            (*info->fprintf_func) (info->stream, "#");
181
            info->target = *(long *) p;
182
            (*info->print_address_func) (info->target, info);
183
            p += 4;
184
            break;
185
          }
186
      case 8:                   /* Autoincrement */
187
        if (regnum == PC_REGNUM)
188
          {
189
            (*info->fprintf_func) (info->stream, "#");
190
            switch (d[1])
191
              {
192
              case 'b':
193
                (*info->fprintf_func) (info->stream, "%d", *p++);
194
                break;
195
 
196
              case 'w':
197
                (*info->fprintf_func) (info->stream, "%d", *(short *) p);
198
                p += 2;
199
                break;
200
 
201
              case 'l':
202
                (*info->fprintf_func) (info->stream, "%d", *(long *) p);
203
                p += 4;
204
                break;
205
 
206
              case 'q':
207
                (*info->fprintf_func) (info->stream, "0x%x%08x",
208
                                       ((long *) p)[1], ((long *) p)[0]);
209
                p += 8;
210
                break;
211
 
212
              case 'o':
213
                (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
214
                                       ((long *) p)[3], ((long *) p)[2],
215
                                       ((long *) p)[1], ((long *) p)[0]);
216
                p += 16;
217
                break;
218
 
219
              case 'f':
220
                if (INVALID_FLOAT (p, 4))
221
                  (*info->fprintf_func) (info->stream,
222
                                         "<<invalid float 0x%x>>",
223
                                         *(int *) p);
224
                else
225
                  (*info->fprintf_func) (info->stream, "%f", *(float *) p);
226
                p += 4;
227
                break;
228
 
229
              case 'd':
230
                if (INVALID_FLOAT (p, 8))
231
                  (*info->fprintf_func) (info->stream,
232
                                         "<<invalid float 0x%x%08x>>",
233
                                         ((long *) p)[1], ((long *) p)[0]);
234
                else
235
                  (*info->fprintf_func) (info->stream, "%f", *(double *) p);
236
                p += 8;
237
                break;
238
 
239
              case 'g':
240
                (*info->fprintf_func) (info->stream, "g-float");
241
                p += 8;
242
                break;
243
 
244
              case 'h':
245
                (*info->fprintf_func) (info->stream, "h-float");
246
                p += 16;
247
                break;
248
 
249
              }
250
          }
251
        else
252
          (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
253
        break;
254
 
255
      case 11:                  /* Byte displacement deferred */
256
        (*info->fprintf_func) (info->stream, "@");
257
      case 10:                  /* Byte displacement */
258
        if (regnum == PC_REGNUM)
259
          {
260
            info->target = addr + *p + 2;
261
            (*info->print_address_func) (info->target, info);
262
          }
263
        else
264
          (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
265
        p += 1;
266
        break;
267
 
268
      case 13:                  /* Word displacement deferred */
269
        (*info->fprintf_func) (info->stream, "@");
270
      case 12:                  /* Word displacement */
271
        if (regnum == PC_REGNUM)
272
          {
273
            info->target = addr + *(short *) p + 3;
274
            (*info->print_address_func) (info->target, info);
275
          }
276
        else
277
          (*info->fprintf_func) (info->stream, "%d(%s)",
278
                                 *(short *) p, REGISTER_NAME (regnum));
279
        p += 2;
280
        break;
281
 
282
      case 15:                  /* Long displacement deferred */
283
        (*info->fprintf_func) (info->stream, "@");
284
      case 14:                  /* Long displacement */
285
        if (regnum == PC_REGNUM)
286
          {
287
            info->target = addr + *(short *) p + 5;
288
            (*info->print_address_func) (info->target, info);
289
          }
290
        else
291
          (*info->fprintf_func) (info->stream, "%d(%s)",
292
                                 *(long *) p, REGISTER_NAME (regnum));
293
        p += 4;
294
      }
295
 
296
  return (unsigned char *) p;
297
}
298
 
299
void
300
_initialize_vax_tdep (void)
301
{
302
  tm_print_insn = vax_print_insn;
303
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.