]> Git Repo - binutils.git/blob - gdb/sh-tdep.c
keep nm-irix5.h
[binutils.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                 [email protected]
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.042211 seconds and 4 git commands to generate.