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