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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [vax-tdep.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* Print VAX instructions for GDB, the GNU debugger.
2
   Copyright 1986, 1989, 1991, 1992, 1996 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
#include "defs.h"
22
#include "symtab.h"
23
#include "opcode/vax.h"
24
 
25
/* Vax instructions are never longer than this.  */
26
#define MAXLEN 62
27
 
28
/* Number of elements in the opcode table.  */
29
#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
30
 
31
static unsigned char *print_insn_arg ();
32
 
33
/* Advance PC across any function entry prologue instructions
34
   to reach some "real" code.  */
35
 
36
CORE_ADDR
37
vax_skip_prologue (pc)
38
     CORE_ADDR pc;
39
{
40
  register int op = (unsigned char) read_memory_integer (pc, 1);
41
  if (op == 0x11)
42
    pc += 2;                    /* skip brb */
43
  if (op == 0x31)
44
    pc += 3;                    /* skip brw */
45
  if (op == 0xC2
46
      && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
47
    pc += 3;                    /* skip subl2 */
48
  if (op == 0x9E
49
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
50
      && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
51
    pc += 4;                    /* skip movab */
52
  if (op == 0x9E
53
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
54
      && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
55
    pc += 5;                    /* skip movab */
56
  if (op == 0x9E
57
      && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
58
      && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
59
    pc += 7;                    /* skip movab */
60
  return pc;
61
}
62
 
63
/* Return number of args passed to a frame.
64
   Can return -1, meaning no way to tell.  */
65
 
66
int
67
vax_frame_num_args (fi)
68
     struct frame_info *fi;
69
{
70
  return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
71
}
72
 
73
 
74
 
75
/* Print the vax instruction at address MEMADDR in debugged memory,
76
   from disassembler info INFO.
77
   Returns length of the instruction, in bytes.  */
78
 
79
static int
80
vax_print_insn (memaddr, info)
81
     CORE_ADDR memaddr;
82
     disassemble_info *info;
83
{
84
  unsigned char buffer[MAXLEN];
85
  register int i;
86
  register unsigned char *p;
87
  register 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 (d, p, addr, info)
130
     char *d;
131
     register char *p;
132
     CORE_ADDR addr;
133
     disassemble_info *info;
134
{
135
  register int regnum = *p & 0xf;
136
  float floatlitbuf;
137
 
138
  if (*d == 'b')
139
    {
140
      if (d[1] == 'b')
141
        (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
142
      else
143
        {
144
          (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
145
          p += 2;
146
        }
147
    }
148
  else
149
    switch ((*p++ >> 4) & 0xf)
150
      {
151
      case 0:
152
      case 1:
153
      case 2:
154
      case 3:                   /* Literal mode */
155
        if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
156
          {
157
            *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
158
            (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
159
          }
160
        else
161
          (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
162
        break;
163
 
164
      case 4:                   /* Indexed */
165
        p = (char *) print_insn_arg (d, p, addr + 1, info);
166
        (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
167
        break;
168
 
169
      case 5:                   /* Register */
170
        (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
171
        break;
172
 
173
      case 7:                   /* Autodecrement */
174
        (*info->fprintf_func) (info->stream, "-");
175
      case 6:                   /* Register deferred */
176
        (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
177
        break;
178
 
179
      case 9:                   /* Autoincrement deferred */
180
        (*info->fprintf_func) (info->stream, "@");
181
        if (regnum == PC_REGNUM)
182
          {
183
            (*info->fprintf_func) (info->stream, "#");
184
            info->target = *(long *) p;
185
            (*info->print_address_func) (info->target, info);
186
            p += 4;
187
            break;
188
          }
189
      case 8:                   /* Autoincrement */
190
        if (regnum == PC_REGNUM)
191
          {
192
            (*info->fprintf_func) (info->stream, "#");
193
            switch (d[1])
194
              {
195
              case 'b':
196
                (*info->fprintf_func) (info->stream, "%d", *p++);
197
                break;
198
 
199
              case 'w':
200
                (*info->fprintf_func) (info->stream, "%d", *(short *) p);
201
                p += 2;
202
                break;
203
 
204
              case 'l':
205
                (*info->fprintf_func) (info->stream, "%d", *(long *) p);
206
                p += 4;
207
                break;
208
 
209
              case 'q':
210
                (*info->fprintf_func) (info->stream, "0x%x%08x",
211
                                       ((long *) p)[1], ((long *) p)[0]);
212
                p += 8;
213
                break;
214
 
215
              case 'o':
216
                (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
217
                                       ((long *) p)[3], ((long *) p)[2],
218
                                       ((long *) p)[1], ((long *) p)[0]);
219
                p += 16;
220
                break;
221
 
222
              case 'f':
223
                if (INVALID_FLOAT (p, 4))
224
                  (*info->fprintf_func) (info->stream,
225
                                         "<<invalid float 0x%x>>",
226
                                         *(int *) p);
227
                else
228
                  (*info->fprintf_func) (info->stream, "%f", *(float *) p);
229
                p += 4;
230
                break;
231
 
232
              case 'd':
233
                if (INVALID_FLOAT (p, 8))
234
                  (*info->fprintf_func) (info->stream,
235
                                         "<<invalid float 0x%x%08x>>",
236
                                         ((long *) p)[1], ((long *) p)[0]);
237
                else
238
                  (*info->fprintf_func) (info->stream, "%f", *(double *) p);
239
                p += 8;
240
                break;
241
 
242
              case 'g':
243
                (*info->fprintf_func) (info->stream, "g-float");
244
                p += 8;
245
                break;
246
 
247
              case 'h':
248
                (*info->fprintf_func) (info->stream, "h-float");
249
                p += 16;
250
                break;
251
 
252
              }
253
          }
254
        else
255
          (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
256
        break;
257
 
258
      case 11:                  /* Byte displacement deferred */
259
        (*info->fprintf_func) (info->stream, "@");
260
      case 10:                  /* Byte displacement */
261
        if (regnum == PC_REGNUM)
262
          {
263
            info->target = addr + *p + 2;
264
            (*info->print_address_func) (info->target, info);
265
          }
266
        else
267
          (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
268
        p += 1;
269
        break;
270
 
271
      case 13:                  /* Word displacement deferred */
272
        (*info->fprintf_func) (info->stream, "@");
273
      case 12:                  /* Word displacement */
274
        if (regnum == PC_REGNUM)
275
          {
276
            info->target = addr + *(short *) p + 3;
277
            (*info->print_address_func) (info->target, info);
278
          }
279
        else
280
          (*info->fprintf_func) (info->stream, "%d(%s)",
281
                                 *(short *) p, REGISTER_NAME (regnum));
282
        p += 2;
283
        break;
284
 
285
      case 15:                  /* Long displacement deferred */
286
        (*info->fprintf_func) (info->stream, "@");
287
      case 14:                  /* Long displacement */
288
        if (regnum == PC_REGNUM)
289
          {
290
            info->target = addr + *(short *) p + 5;
291
            (*info->print_address_func) (info->target, info);
292
          }
293
        else
294
          (*info->fprintf_func) (info->stream, "%d(%s)",
295
                                 *(long *) p, REGISTER_NAME (regnum));
296
        p += 4;
297
      }
298
 
299
  return (unsigned char *) p;
300
}
301
 
302
void
303
_initialize_vax_tdep ()
304
{
305
  tm_print_insn = vax_print_insn;
306
}

powered by: WebSVN 2.1.0

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