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