* remote-e7000.c (HARD_BREAKPOINTS): Reenable.
[deliverable/binutils-gdb.git] / gdb / sh-tdep.c
1 /* Target-machine dependent code for Hitachi Super-H, for GDB.
2 Copyright (C) 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21 Contributed by Steve Chamberlain
22 sac@cygnus.com
23 */
24
25 #include "defs.h"
26 #include "frame.h"
27 #include "obstack.h"
28 #include "symtab.h"
29 #include "gdbtypes.h"
30 #include "gdbcmd.h"
31 #include "value.h"
32 #include "dis-asm.h"
33 #include "../opcodes/sh-opc.h"
34
35
36
37 /* Prologue looks like
38 [mov.l <regs>,@-r15]...
39 [sts.l pr,@-r15]
40 [mov.l r14,@-r15]
41 [mov r15,r14]
42 */
43
44 #define IS_STS(x) ((x) == 0x4f22)
45 #define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06)
46 #define GET_PUSHED_REG(x) (((x) >> 4) & 0xf)
47 #define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
48 #define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
49 #define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00)
50 #define IS_SHLL_R3(x) ((x) == 0x4300)
51 #define IS_ADD_R3SP(x) ((x) == 0x3f3c)
52
53 /* Skip any prologue before the guts of a function */
54
55 CORE_ADDR
56 sh_skip_prologue (start_pc)
57 CORE_ADDR start_pc;
58 {
59 int w;
60
61 w = read_memory_integer (start_pc, 2);
62 while (IS_STS (w)
63 || IS_PUSH (w)
64 || IS_MOV_SP_FP (w)
65 || IS_MOV_R3 (w)
66 || IS_ADD_R3SP (w)
67 || IS_ADD_SP (w)
68 || IS_SHLL_R3 (w))
69 {
70 start_pc += 2;
71 w = read_memory_integer (start_pc, 2);
72 }
73
74 return start_pc;
75 }
76
77 /* Disassemble an instruction */
78
79 int
80 print_insn (memaddr, stream)
81 CORE_ADDR memaddr;
82 GDB_FILE *stream;
83 {
84 disassemble_info info;
85
86 GDB_INIT_DISASSEMBLE_INFO (info, stream);
87
88 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
89 return print_insn_sh (memaddr, &info);
90 else
91 return print_insn_shl (memaddr, &info);
92 }
93 /* Given a GDB frame, determine the address of the calling function's frame.
94 This will be used to create a new GDB frame struct, and then
95 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
96
97 For us, the frame address is its stack pointer value, so we look up
98 the function prologue to determine the caller's sp value, and return it. */
99
100 CORE_ADDR
101 sh_frame_chain (frame)
102 struct frame_info *frame;
103 {
104 if (!inside_entry_file (frame->pc))
105 return read_memory_integer (FRAME_FP (frame) + frame->f_offset, 4);
106 else
107 return 0;
108 }
109
110 /* Put here the code to store, into a struct frame_saved_regs,
111 the addresses of the saved registers of frame described by FRAME_INFO.
112 This includes special registers such as pc and fp saved in special
113 ways in the stack frame. sp is even more special:
114 the address we return for it IS the sp for the next frame. */
115
116
117 void
118 frame_find_saved_regs (fi, fsr)
119 struct frame_info *fi;
120 struct frame_saved_regs *fsr;
121 {
122 int where[NUM_REGS];
123 int rn;
124 int have_fp = 0;
125 int depth;
126 int pc;
127 int opc;
128 int insn;
129 int hadf;
130 int r3_val = 0;
131
132 opc = pc = get_pc_function_start (fi->pc);
133
134 insn = read_memory_integer (pc, 2);
135
136 fi->leaf_function = 1;
137 fi->f_offset = 0;
138
139 for (rn = 0; rn < NUM_REGS; rn++)
140 where[rn] = -1;
141
142 depth = 0;
143
144 /* Loop around examining the prologue insns, but give up
145 after 15 of them, since we're getting silly then */
146 while (pc < opc + 15 * 2)
147 {
148 /* See where the registers will be saved to */
149 if (IS_PUSH (insn))
150 {
151 pc += 2;
152 rn = GET_PUSHED_REG (insn);
153 where[rn] = depth;
154 insn = read_memory_integer (pc, 2);
155 depth += 4;
156 }
157 else if (IS_STS (insn))
158 {
159 pc += 2;
160 where[PR_REGNUM] = depth;
161 insn = read_memory_integer (pc, 2);
162 /* If we're storing the pr then this isn't a leaf */
163 fi->leaf_function = 0;
164 depth += 4;
165 }
166 else if (IS_MOV_R3 (insn))
167 {
168 r3_val = (char) (insn & 0xff);
169 pc += 2;
170 insn = read_memory_integer (pc, 2);
171 }
172 else if (IS_SHLL_R3 (insn))
173 {
174 r3_val <<= 1;
175 pc += 2;
176 insn = read_memory_integer (pc, 2);
177 }
178 else if (IS_ADD_R3SP (insn))
179 {
180 depth += -r3_val;
181 pc += 2;
182 insn = read_memory_integer (pc, 2);
183 }
184 else if (IS_ADD_SP (insn))
185 {
186 pc += 2;
187 depth += -((char) (insn & 0xff));
188 insn = read_memory_integer (pc, 2);
189 }
190 else
191 break;
192 }
193
194 /* Now we know how deep things are, we can work out their addresses */
195
196 for (rn = 0; rn < NUM_REGS; rn++)
197 {
198 if (where[rn] >= 0)
199 {
200 if (rn == FP_REGNUM)
201 have_fp = 1;
202
203 fsr->regs[rn] = fi->frame - where[rn] + depth - 4;
204 }
205 else
206 {
207 fsr->regs[rn] = 0;
208 }
209 }
210
211 if (have_fp)
212 {
213 fsr->regs[SP_REGNUM] = read_memory_integer (fsr->regs[FP_REGNUM], 4);
214 }
215 else
216 {
217 fsr->regs[SP_REGNUM] = fi->frame - 4;
218 }
219
220 fi->f_offset = depth - where[FP_REGNUM] - 4;
221 /* Work out the return pc - either from the saved pr or the pr
222 value */
223 /* Just called, so dig out the real return */
224 if (fi->return_pc == 0)
225 {
226 fi->return_pc = read_register (PR_REGNUM) + 4;
227 }
228 else
229 {
230
231 if (fsr->regs[PR_REGNUM])
232 {
233 fi->return_pc = read_memory_integer (fsr->regs[PR_REGNUM], 4) + 4;
234 }
235 else
236 {
237 fi->return_pc = read_register (PR_REGNUM) + 4;
238 }
239 }
240 }
241
242 /* initialize the extra info saved in a FRAME */
243
244 void
245 init_extra_frame_info (fromleaf, fi)
246 int fromleaf;
247 struct frame_info *fi;
248 {
249 struct frame_saved_regs dummy;
250 frame_find_saved_regs (fi, &dummy);
251 }
252
253
254 /* Discard from the stack the innermost frame,
255 restoring all saved registers. */
256
257 void
258 pop_frame ()
259 {
260 register struct frame_info *frame = get_current_frame ();
261 register CORE_ADDR fp;
262 register int regnum;
263 struct frame_saved_regs fsr;
264
265 fp = FRAME_FP (frame);
266 get_frame_saved_regs (frame, &fsr);
267
268 /* Copy regs from where they were saved in the frame */
269 for (regnum = 0; regnum < NUM_REGS; regnum++)
270 {
271 if (fsr.regs[regnum])
272 {
273 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
274 }
275 }
276
277 write_register (PC_REGNUM, frame->return_pc);
278 write_register (SP_REGNUM, fp + 4);
279 flush_cached_frames ();
280 }
281
282 /* Print the registers in a form similar to the E7000 */
283
284 static void
285 show_regs (args, from_tty)
286 char *args;
287 int from_tty;
288 {
289 printf_filtered ("PC=%08x SR=%08x PR=%08x MACH=%08x MACHL=%08x\n",
290 read_register (PC_REGNUM),
291 read_register (SR_REGNUM),
292 read_register (PR_REGNUM),
293 read_register (MACH_REGNUM),
294 read_register (MACL_REGNUM));
295
296 printf_filtered ("R0-R7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
297 read_register (0),
298 read_register (1),
299 read_register (2),
300 read_register (3),
301 read_register (4),
302 read_register (5),
303 read_register (6),
304 read_register (7));
305 printf_filtered ("R8-R15 %08x %08x %08x %08x %08x %08x %08x %08x\n",
306 read_register (8),
307 read_register (9),
308 read_register (10),
309 read_register (11),
310 read_register (12),
311 read_register (13),
312 read_register (14),
313 read_register (15));
314 }
315 \f
316
317 void
318 _initialize_sh_tdep ()
319 {
320 extern int sim_memory_size;
321 /* FIXME, there should be a way to make a CORE_ADDR variable settable. */
322 add_show_from_set
323 (add_set_cmd ("memory_size", class_support, var_uinteger,
324 (char *) &sim_memory_size,
325 "Set simulated memory size of simulator target.", &setlist),
326 &showlist);
327
328 add_com ("regs", class_vars, show_regs, "Print all registers");
329 }
This page took 0.054882 seconds and 5 git commands to generate.