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