Support for Hitachi SH
[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 /* Prologue looks like
37    [mov.l       <regs>,@-r15]...
38    [sts.l       pr,@-r15]
39    [mov.l       r14,@-r15]
40    [mov         r15,r14]
41 */
42
43 #define IS_STS(x)               ((x) == 0x4f22)
44 #define IS_PUSH(x)              (((x) & 0xff0f) == 0x2f06)
45 #define GET_PUSHED_REG(x)       (((x) >> 4) & 0xf)
46 #define IS_MOV_SP_FP(x)         ((x) == 0x6ef3)
47 #define IS_ADD_SP(x)            (((x) & 0xff00) == 0x7f00)
48
49
50 /* Skip any prologue before the guts of a function */
51
52 CORE_ADDR
53 sh_skip_prologue (start_pc)
54      CORE_ADDR start_pc;
55
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     {
64       start_pc += 2;
65       w = read_memory_integer (start_pc, 2);
66     }
67
68   return start_pc;
69 }
70
71 /* Disassemble an instruction */
72
73 int
74 print_insn (memaddr, stream)
75      CORE_ADDR memaddr;
76      FILE *stream;
77 {
78   disassemble_info info;
79   GDB_INIT_DISASSEMBLE_INFO (info, stream);
80   return print_insn_sh (memaddr, &info);
81 }
82
83 /* Given a GDB frame, determine the address of the calling function's frame.
84    This will be used to create a new GDB frame struct, and then
85    INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
86
87    For us, the frame address is its stack pointer value, so we look up
88    the function prologue to determine the caller's sp value, and return it.  */
89
90 FRAME_ADDR
91 sh_frame_chain (thisframe)
92      FRAME thisframe;
93 {
94   if (!inside_entry_file (thisframe->pc))
95     return (read_memory_integer (FRAME_FP (thisframe), 4));
96   else
97     return 0;
98 }
99
100 /* Put here the code to store, into a struct frame_saved_regs,
101    the addresses of the saved registers of frame described by FRAME_INFO.
102    This includes special registers such as pc and fp saved in special
103    ways in the stack frame.  sp is even more special:
104    the address we return for it IS the sp for the next frame. */
105
106
107 void
108 frame_find_saved_regs (fi, fsr)
109      struct frame_info *fi;
110      struct frame_saved_regs *fsr;
111 {
112   int where[16];
113   int rn;
114   int have_fp = 0;
115   int depth;
116   int pc;
117   int opc;
118   int insn;
119
120   opc = pc = get_pc_function_start (fi->pc);
121
122   insn = read_memory_integer (pc, 2);
123
124   for (rn = 0; rn < NUM_REGS; rn++)
125     where[rn] = -1;
126
127   depth = 0;
128
129   /* Loop around examining the prologue insns, but give up
130      after 15 of them, since we're getting silly then */
131   while (pc < opc + 15 * 2)
132     {
133       /* See where the registers will be saved to */
134       if (IS_PUSH (insn))
135         {
136           pc += 2;
137           rn = GET_PUSHED_REG (insn);
138           where[rn] = depth;
139           insn = read_memory_integer (pc, 2);
140           depth += 4;
141         }
142       else if (IS_STS (insn))
143         {
144           pc += 2;
145           where[PR_REGNUM] = depth;
146           insn = read_memory_integer (pc, 2);
147           depth += 4;
148         }
149       else if (IS_ADD_SP (insn))
150         {
151           pc += 2;
152           depth += -((char) (insn & 0xff));
153           insn = read_memory_integer (pc, 2);
154         }
155       else break;
156     }
157
158   /* Now we know how deep things are, we can work out their addresses */
159
160   for (rn = 0; rn < NUM_REGS; rn++)
161     {
162       if (where[rn] >= 0)
163         {
164           if (rn == FP_REGNUM)
165             have_fp = 1;
166
167           fsr->regs[rn] = fi->frame - where[rn] + depth - 4;
168         }
169       else
170         {
171           fsr->regs[rn] = 0;
172         }
173     }
174
175   if (have_fp)
176     {
177
178       fsr->regs[SP_REGNUM] = read_memory_integer (fsr->regs[FP_REGNUM], 4);
179     }
180   else
181     {
182       fsr->regs[SP_REGNUM] = fi->frame - 4;
183     }
184
185   /* Remember the address of the frame pointer */
186
187   /* Work out the return pc - either from the saved pr or the pr
188      value */
189
190   if (fsr->regs[PR_REGNUM])
191     {
192       fi->return_pc = read_memory_integer (fsr->regs[PR_REGNUM], 4) + 4;
193     }
194   else
195     {
196       fi->return_pc = read_register (PR_REGNUM) + 4;
197     }
198 }
199
200 /* initialize the extra info saved in a FRAME */
201
202 void
203 init_extra_frame_info (fromleaf, fi)
204      int fromleaf;
205      struct frame_info *fi;
206 {
207   struct frame_saved_regs dummy;
208   frame_find_saved_regs (fi, &dummy);
209 }
210
211
212 /* Discard from the stack the innermost frame,
213    restoring all saved registers.  */
214
215 void
216 pop_frame ()
217 {
218   register FRAME frame = get_current_frame ();
219   register CORE_ADDR fp;
220   register int regnum;
221   struct frame_saved_regs fsr;
222   struct frame_info *fi;
223
224   fi = get_frame_info (frame);
225   fp = fi->frame;
226   get_frame_saved_regs (fi, &fsr);
227
228   /* Copy regs from where they were saved in the frame */
229   for (regnum = 0; regnum < NUM_REGS; regnum++)
230     {
231       if (fsr.regs[regnum])
232         {
233           write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
234         }
235     }
236
237   write_register (PC_REGNUM, fi->return_pc);
238   write_register (SP_REGNUM, fp + 4);
239   flush_cached_frames ();
240   set_current_frame (create_new_frame (read_register (FP_REGNUM),
241                                        read_pc ()));
242 }