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