The point of these changes is to avoid reading the frame pointer
[external/binutils.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
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)
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)
53
54 /* Skip any prologue before the guts of a function */
55
56 CORE_ADDR
57 sh_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)
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))
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
81 int
82 print_insn (memaddr, stream)
83      CORE_ADDR memaddr;
84      GDB_FILE *stream;
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
98 FRAME_ADDR
99 sh_frame_chain (thisframe)
100      FRAME thisframe;
101 {
102   if (!inside_entry_file (thisframe->pc))
103     return (read_memory_integer (FRAME_FP (thisframe) + thisframe->f_offset, 4));
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
115 void
116 frame_find_saved_regs (fi, fsr)
117      struct frame_info *fi;
118      struct frame_saved_regs *fsr;
119 {
120   int where[NUM_REGS];
121   int rn;
122   int have_fp = 0;
123   int depth;
124   int pc;
125   int opc;
126   int insn;
127   int hadf;
128   int r3_val = 0;
129
130   opc = pc = get_pc_function_start (fi->pc);
131
132   insn = read_memory_integer (pc, 2);
133
134   fi->leaf_function = 1;
135   fi->f_offset = 0;
136
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);
160           /* If we're storing the pr then this isn't a leaf */
161           fi->leaf_function = 0;
162           depth += 4;
163         }
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         }
182       else if (IS_ADD_SP (insn))
183         {
184           pc += 2;
185           depth += -((char) (insn & 0xff));
186           insn = read_memory_integer (pc, 2);
187         }
188       else
189         break;
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     {
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
218   fi->f_offset = depth - where[FP_REGNUM] - 4;
219   /* Work out the return pc - either from the saved pr or the pr
220      value */
221   /* Just called, so dig out the real return */
222   if (fi->return_pc == 0)
223     {
224       fi->return_pc = read_register (PR_REGNUM) + 4;
225     }
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   }
237 }
238
239 /* initialize the extra info saved in a FRAME */
240
241 void
242 init_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
254 void
255 pop_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 ();
279 }
280
281 /* Print the registers in a form similar to the E7000 */
282 static void
283 show_regs (args, from_tty)
284 char *args;
285 int 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 }
313 \f
314
315 void
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);
325
326   add_com("regs", class_vars, show_regs, "Print all registers");
327 }