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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [ns32k-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 104 markom
/* Print NS 32000 instructions for GDB, the GNU debugger.
2
   Copyright 1986, 1988, 1991, 1992, 1994, 1995
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
 
24
void
25
_initialize_ns32k_tdep ()
26
{
27
  tm_print_insn = print_insn_ns32k;
28
}
29
 
30
/* Advance PC across any function entry prologue instructions
31
   to reach some "real" code.  */
32
 
33
CORE_ADDR
34
merlin_skip_prologue (pc)
35
     CORE_ADDR pc;
36
{
37
  register int op = read_memory_integer (pc, 1);
38
  if (op == 0x82)
39
    {
40
      op = read_memory_integer (pc + 2, 1);
41
      if ((op & 0x80) == 0)
42
        pc += 3;
43
      else if ((op & 0xc0) == 0x80)
44
        pc += 4;
45
      else
46
        pc += 6;
47
    }
48
  return pc;
49
}
50
 
51
CORE_ADDR
52
umax_skip_prologue (pc)
53
     CORE_ADDR pc;
54
{
55
  register unsigned char op = read_memory_integer (pc, 1);
56
  if (op == 0x82)
57
    {
58
      op = read_memory_integer (pc + 2, 1);
59
      if ((op & 0x80) == 0)
60
        pc += 3;
61
      else if ((op & 0xc0) == 0x80)
62
        pc += 4;
63
      else
64
        pc += 6;
65
    }
66
  return pc;
67
}
68
 
69
/* Return number of args passed to a frame.
70
   Can return -1, meaning no way to tell.  */
71
 
72
int
73
merlin_frame_num_args (fi)
74
     struct frame_info *fi;
75
{
76
  int numargs;
77
  CORE_ADDR pc;
78
  int insn;
79
  int addr_mode;
80
  int width;
81
 
82
  pc = FRAME_SAVED_PC (fi);
83
  insn = read_memory_integer (pc, 2);
84
  addr_mode = (insn >> 11) & 0x1f;
85
  insn = insn & 0x7ff;
86
  if ((insn & 0x7fc) == 0x57c
87
      && addr_mode == 0x14)     /* immediate */
88
    {
89
      if (insn == 0x57c)        /* adjspb */
90
        width = 1;
91
      else if (insn == 0x57d)   /* adjspw */
92
        width = 2;
93
      else if (insn == 0x57f)   /* adjspd */
94
        width = 4;
95
      numargs = read_memory_integer (pc + 2, width);
96
      if (width > 1)
97
        flip_bytes (&numargs, width);
98
      numargs = -sign_extend (numargs, width * 8) / 4;
99
    }
100
  else
101
    numargs = -1;
102
  return numargs;
103
}
104
 
105
 
106
/* Return number of args passed to a frame.
107
   Can return -1, meaning no way to tell.
108
   Encore's C compiler often reuses same area on stack for args,
109
   so this will often not work properly.  If the arg names
110
   are known, it's likely most of them will be printed. */
111
int
112
umax_frame_num_args (fi)
113
     struct frame_info *fi;
114
{
115
  int numargs;
116
  CORE_ADDR pc;
117
  CORE_ADDR enter_addr;
118
  unsigned int insn;
119
  unsigned int addr_mode;
120
  int width;
121
 
122
  numargs = -1;
123
  enter_addr = ns32k_get_enter_addr ((fi)->pc);
124
  if (enter_addr > 0)
125
    {
126
      pc = ((enter_addr == 1)
127
            ? SAVED_PC_AFTER_CALL (fi)
128
            : FRAME_SAVED_PC (fi));
129
      insn = read_memory_integer (pc, 2);
130
      addr_mode = (insn >> 11) & 0x1f;
131
      insn = insn & 0x7ff;
132
      if ((insn & 0x7fc) == 0x57c
133
          && addr_mode == 0x14) /* immediate */
134
        {
135
          if (insn == 0x57c)    /* adjspb */
136
            width = 1;
137
          else if (insn == 0x57d)       /* adjspw */
138
            width = 2;
139
          else if (insn == 0x57f)       /* adjspd */
140
            width = 4;
141
          numargs = read_memory_integer (pc + 2, width);
142
          if (width > 1)
143
            flip_bytes (&numargs, width);
144
          numargs = -sign_extend (numargs, width * 8) / 4;
145
        }
146
    }
147
  return numargs;
148
}
149
 
150
 
151
sign_extend (value, bits)
152
{
153
  value = value & ((1 << bits) - 1);
154
  return (value & (1 << (bits - 1))
155
          ? value | (~((1 << bits) - 1))
156
          : value);
157
}
158
 
159
void
160
flip_bytes (ptr, count)
161
     char *ptr;
162
     int count;
163
{
164
  char tmp;
165
 
166
  while (count > 0)
167
    {
168
      tmp = *ptr;
169
      ptr[0] = ptr[count - 1];
170
      ptr[count - 1] = tmp;
171
      ptr++;
172
      count -= 2;
173
    }
174
}
175
 
176
/* Return the number of locals in the current frame given a pc
177
   pointing to the enter instruction.  This is used in the macro
178
   FRAME_FIND_SAVED_REGS.  */
179
 
180
int
181
ns32k_localcount (enter_pc)
182
     CORE_ADDR enter_pc;
183
{
184
  unsigned char localtype;
185
  int localcount;
186
 
187
  localtype = read_memory_integer (enter_pc + 2, 1);
188
  if ((localtype & 0x80) == 0)
189
    localcount = localtype;
190
  else if ((localtype & 0xc0) == 0x80)
191
    localcount = (((localtype & 0x3f) << 8)
192
                  | (read_memory_integer (enter_pc + 3, 1) & 0xff));
193
  else
194
    localcount = (((localtype & 0x3f) << 24)
195
                  | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
196
                  | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
197
                  | (read_memory_integer (enter_pc + 5, 1) & 0xff));
198
  return localcount;
199
}
200
 
201
 
202
/* Nonzero if instruction at PC is a return instruction.  */
203
 
204
static int
205
ns32k_about_to_return (pc)
206
     CORE_ADDR pc;
207
{
208
  return (read_memory_integer (pc, 1) == 0x12);
209
}
210
 
211
 
212
/*
213
 * Get the address of the enter opcode for the function
214
 * containing PC, if there is an enter for the function,
215
 * and if the pc is between the enter and exit.
216
 * Returns positive address if pc is between enter/exit,
217
 * 1 if pc before enter or after exit, 0 otherwise.
218
 */
219
 
220
CORE_ADDR
221
ns32k_get_enter_addr (pc)
222
     CORE_ADDR pc;
223
{
224
  CORE_ADDR enter_addr;
225
  unsigned char op;
226
 
227
  if (pc == 0)
228
    return 0;
229
 
230
  if (ns32k_about_to_return (pc))
231
    return 1;                   /* after exit */
232
 
233
  enter_addr = get_pc_function_start (pc);
234
 
235
  if (pc == enter_addr)
236
    return 1;                   /* before enter */
237
 
238
  op = read_memory_integer (enter_addr, 1);
239
 
240
  if (op != 0x82)
241
    return 0;                    /* function has no enter/exit */
242
 
243
  return enter_addr;            /* pc is between enter and exit */
244
}

powered by: WebSVN 2.1.0

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