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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [ns32k-tdep.c] - Blame information for rev 1768

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

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