* monitor.c (monitor_load_srec monitor_make_srec): Move all
[deliverable/binutils-gdb.git] / gdb / sh-tdep.c
1 /* Target-dependent code for Hitachi Super-H, for GDB.
2 Copyright (C) 1993, 1994, 1995 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "gdbcore.h"
32 #include "value.h"
33 #include "dis-asm.h"
34
35 /* Prologue looks like
36 [mov.l <regs>,@-r15]...
37 [sts.l pr,@-r15]
38 [mov.l r14,@-r15]
39 [mov r15,r14]
40 */
41
42 #define IS_STS(x) ((x) == 0x4f22)
43 #define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06)
44 #define GET_PUSHED_REG(x) (((x) >> 4) & 0xf)
45 #define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
46 #define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
47 #define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00)
48 #define IS_SHLL_R3(x) ((x) == 0x4300)
49 #define IS_ADD_R3SP(x) ((x) == 0x3f3c)
50
51 /* Skip any prologue before the guts of a function */
52
53 CORE_ADDR
54 sh_skip_prologue (start_pc)
55 CORE_ADDR start_pc;
56 {
57 int w;
58
59 w = read_memory_integer (start_pc, 2);
60 while (IS_STS (w)
61 || IS_PUSH (w)
62 || IS_MOV_SP_FP (w)
63 || IS_MOV_R3 (w)
64 || IS_ADD_R3SP (w)
65 || IS_ADD_SP (w)
66 || IS_SHLL_R3 (w))
67 {
68 start_pc += 2;
69 w = read_memory_integer (start_pc, 2);
70 }
71
72 return start_pc;
73 }
74
75 /* Disassemble an instruction. */
76
77 int
78 gdb_print_insn_sh (memaddr, info)
79 bfd_vma memaddr;
80 disassemble_info *info;
81 {
82 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
83 return print_insn_sh (memaddr, info);
84 else
85 return print_insn_shl (memaddr, info);
86 }
87
88 /* Given a GDB frame, determine the address of the calling function's frame.
89 This will be used to create a new GDB frame struct, and then
90 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
91
92 For us, the frame address is its stack pointer value, so we look up
93 the function prologue to determine the caller's sp value, and return it. */
94
95 CORE_ADDR
96 sh_frame_chain (frame)
97 struct frame_info *frame;
98 {
99 if (!inside_entry_file (frame->pc))
100 return read_memory_integer (FRAME_FP (frame) + frame->f_offset, 4);
101 else
102 return 0;
103 }
104
105 /* Put here the code to store, into a struct frame_saved_regs, the
106 addresses of the saved registers of frame described by FRAME_INFO.
107 This includes special registers such as pc and fp saved in special
108 ways in the stack frame. sp is even more special: the address we
109 return for it IS the sp for the next frame. */
110
111 void
112 frame_find_saved_regs (fi, fsr)
113 struct frame_info *fi;
114 struct frame_saved_regs *fsr;
115 {
116 int where[NUM_REGS];
117 int rn;
118 int have_fp = 0;
119 int depth;
120 int pc;
121 int opc;
122 int insn;
123 int r3_val = 0;
124
125 opc = pc = get_pc_function_start (fi->pc);
126
127 insn = read_memory_integer (pc, 2);
128
129 fi->leaf_function = 1;
130 fi->f_offset = 0;
131
132 for (rn = 0; rn < NUM_REGS; rn++)
133 where[rn] = -1;
134
135 depth = 0;
136
137 /* Loop around examining the prologue insns, but give up
138 after 15 of them, since we're getting silly then */
139 while (pc < opc + 15 * 2)
140 {
141 /* See where the registers will be saved to */
142 if (IS_PUSH (insn))
143 {
144 pc += 2;
145 rn = GET_PUSHED_REG (insn);
146 where[rn] = depth;
147 insn = read_memory_integer (pc, 2);
148 depth += 4;
149 }
150 else if (IS_STS (insn))
151 {
152 pc += 2;
153 where[PR_REGNUM] = depth;
154 insn = read_memory_integer (pc, 2);
155 /* If we're storing the pr then this isn't a leaf */
156 fi->leaf_function = 0;
157 depth += 4;
158 }
159 else if (IS_MOV_R3 (insn))
160 {
161 r3_val = (char) (insn & 0xff);
162 pc += 2;
163 insn = read_memory_integer (pc, 2);
164 }
165 else if (IS_SHLL_R3 (insn))
166 {
167 r3_val <<= 1;
168 pc += 2;
169 insn = read_memory_integer (pc, 2);
170 }
171 else if (IS_ADD_R3SP (insn))
172 {
173 depth += -r3_val;
174 pc += 2;
175 insn = read_memory_integer (pc, 2);
176 }
177 else if (IS_ADD_SP (insn))
178 {
179 pc += 2;
180 depth += -((char) (insn & 0xff));
181 insn = read_memory_integer (pc, 2);
182 }
183 else
184 break;
185 }
186
187 /* Now we know how deep things are, we can work out their addresses */
188
189 for (rn = 0; rn < NUM_REGS; rn++)
190 {
191 if (where[rn] >= 0)
192 {
193 if (rn == FP_REGNUM)
194 have_fp = 1;
195
196 fsr->regs[rn] = fi->frame - where[rn] + depth - 4;
197 }
198 else
199 {
200 fsr->regs[rn] = 0;
201 }
202 }
203
204 if (have_fp)
205 {
206 fsr->regs[SP_REGNUM] = read_memory_integer (fsr->regs[FP_REGNUM], 4);
207 }
208 else
209 {
210 fsr->regs[SP_REGNUM] = fi->frame - 4;
211 }
212
213 fi->f_offset = depth - where[FP_REGNUM] - 4;
214 /* Work out the return pc - either from the saved pr or the pr
215 value */
216
217 if (fsr->regs[PR_REGNUM])
218 fi->return_pc = read_memory_integer (fsr->regs[PR_REGNUM], 4);
219 else
220 fi->return_pc = read_register (PR_REGNUM);
221 }
222
223 /* initialize the extra info saved in a FRAME */
224
225 void
226 init_extra_frame_info (fromleaf, fi)
227 int fromleaf;
228 struct frame_info *fi;
229 {
230 struct frame_saved_regs dummy;
231
232 if (fi->next)
233 fi->pc = fi->next->return_pc;
234
235 frame_find_saved_regs (fi, &dummy);
236 }
237
238
239 /* Discard from the stack the innermost frame,
240 restoring all saved registers. */
241
242 void
243 pop_frame ()
244 {
245 register struct frame_info *frame = get_current_frame ();
246 register CORE_ADDR fp;
247 register int regnum;
248 struct frame_saved_regs fsr;
249
250 fp = FRAME_FP (frame);
251 get_frame_saved_regs (frame, &fsr);
252
253 /* Copy regs from where they were saved in the frame */
254 for (regnum = 0; regnum < NUM_REGS; regnum++)
255 {
256 if (fsr.regs[regnum])
257 {
258 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
259 }
260 }
261
262 write_register (PC_REGNUM, frame->return_pc);
263 write_register (SP_REGNUM, fp + 4);
264 flush_cached_frames ();
265 }
266
267 /* Print the registers in a form similar to the E7000 */
268
269 static void
270 show_regs (args, from_tty)
271 char *args;
272 int from_tty;
273 {
274 printf_filtered ("PC=%08x SR=%08x PR=%08x MACH=%08x MACHL=%08x\n",
275 read_register (PC_REGNUM),
276 read_register (SR_REGNUM),
277 read_register (PR_REGNUM),
278 read_register (MACH_REGNUM),
279 read_register (MACL_REGNUM));
280
281 printf_filtered ("R0-R7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
282 read_register (0),
283 read_register (1),
284 read_register (2),
285 read_register (3),
286 read_register (4),
287 read_register (5),
288 read_register (6),
289 read_register (7));
290 printf_filtered ("R8-R15 %08x %08x %08x %08x %08x %08x %08x %08x\n",
291 read_register (8),
292 read_register (9),
293 read_register (10),
294 read_register (11),
295 read_register (12),
296 read_register (13),
297 read_register (14),
298 read_register (15));
299 }
300 \f
301 void
302 _initialize_sh_tdep ()
303 {
304 tm_print_insn = gdb_print_insn_sh;
305
306 add_com ("regs", class_vars, show_regs, "Print all registers");
307 }
This page took 0.052348 seconds and 5 git commands to generate.