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