* monitor.c: Use int rather than LONGEST for values, since
[deliverable/binutils-gdb.git] / gdb / sh-tdep.c
CommitLineData
66d05e03 1/* Target-dependent code for Hitachi Super-H, for GDB.
00dd4fd9 2 Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
9faacb92
SC
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
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
9faacb92
SC
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"
66d05e03 31#include "gdbcore.h"
9faacb92
SC
32#include "value.h"
33#include "dis-asm.h"
5f2f2809 34
00dd4fd9
SS
35/* Default to the original SH. */
36
37#define DEFAULT_SH_TYPE "sh"
38
39/* This value is the model of SH in use. */
40
41char *sh_processor_type;
42
43char *tmp_sh_processor_type;
44
45/* A set of original names, to be used when restoring back to generic
46 registers from a specific set. */
47
48char *sh_generic_reg_names[] = REGISTER_NAMES;
49
50char *sh_reg_names[] = {
51 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
52 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
53 "pc", "pr", "gbr", "vbr", "mach","macl", "sr",
54 "fpul", "fpscr",
55 "", "", "", "", "", "", "", "",
56 "", "", "", "", "", "", "", "",
57 "", "", "", "", "", "", "", "",
58 "", "", "", "", "", "", "", ""
59};
60
61char *sh3_reg_names[] = {
62 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
63 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
64 "pc", "pr", "gbr", "vbr", "mach","macl","sr",
65 "fpul", "fpscr",
66 "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
67 "fr8", "fr9", "fr10","fr11","fr12","fr13","fr14","fr15",
68 "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
69 "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1"
70};
71
72struct {
73 char *name;
74 char **regnames;
75} sh_processor_type_table[] = {
76 { "sh", sh_reg_names },
77 { "sh3", sh3_reg_names },
78 { NULL, NULL }
79};
80
9faacb92
SC
81/* Prologue looks like
82 [mov.l <regs>,@-r15]...
83 [sts.l pr,@-r15]
84 [mov.l r14,@-r15]
85 [mov r15,r14]
86*/
87
88#define IS_STS(x) ((x) == 0x4f22)
89#define IS_PUSH(x) (((x) & 0xff0f) == 0x2f06)
90#define GET_PUSHED_REG(x) (((x) >> 4) & 0xf)
91#define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
92#define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
c4deed18
SC
93#define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00)
94#define IS_SHLL_R3(x) ((x) == 0x4300)
95#define IS_ADD_R3SP(x) ((x) == 0x3f3c)
9faacb92
SC
96
97/* Skip any prologue before the guts of a function */
98
99CORE_ADDR
100sh_skip_prologue (start_pc)
101 CORE_ADDR start_pc;
9faacb92
SC
102{
103 int w;
104
105 w = read_memory_integer (start_pc, 2);
106 while (IS_STS (w)
107 || IS_PUSH (w)
c4deed18 108 || IS_MOV_SP_FP (w)
5f2f2809
SC
109 || IS_MOV_R3 (w)
110 || IS_ADD_R3SP (w)
111 || IS_ADD_SP (w)
112 || IS_SHLL_R3 (w))
9faacb92
SC
113 {
114 start_pc += 2;
115 w = read_memory_integer (start_pc, 2);
116 }
117
118 return start_pc;
119}
120
18b46e7c 121/* Disassemble an instruction. */
9faacb92
SC
122
123int
18b46e7c
SS
124gdb_print_insn_sh (memaddr, info)
125 bfd_vma memaddr;
126 disassemble_info *info;
9faacb92 127{
5f2f2809 128 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
5076ecd0 129 return print_insn_sh (memaddr, info);
5f2f2809 130 else
5076ecd0 131 return print_insn_shl (memaddr, info);
9faacb92 132}
18b46e7c 133
9faacb92
SC
134/* Given a GDB frame, determine the address of the calling function's frame.
135 This will be used to create a new GDB frame struct, and then
136 INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
137
138 For us, the frame address is its stack pointer value, so we look up
139 the function prologue to determine the caller's sp value, and return it. */
140
669caa9c
SS
141CORE_ADDR
142sh_frame_chain (frame)
143 struct frame_info *frame;
9faacb92 144{
669caa9c
SS
145 if (!inside_entry_file (frame->pc))
146 return read_memory_integer (FRAME_FP (frame) + frame->f_offset, 4);
9faacb92
SC
147 else
148 return 0;
149}
150
66d05e03
SS
151/* Put here the code to store, into a struct frame_saved_regs, the
152 addresses of the saved registers of frame described by FRAME_INFO.
9faacb92 153 This includes special registers such as pc and fp saved in special
66d05e03
SS
154 ways in the stack frame. sp is even more special: the address we
155 return for it IS the sp for the next frame. */
9faacb92
SC
156
157void
158frame_find_saved_regs (fi, fsr)
159 struct frame_info *fi;
160 struct frame_saved_regs *fsr;
161{
7ccb1e44 162 int where[NUM_REGS];
9faacb92
SC
163 int rn;
164 int have_fp = 0;
165 int depth;
166 int pc;
167 int opc;
168 int insn;
c4deed18 169 int r3_val = 0;
9faacb92
SC
170
171 opc = pc = get_pc_function_start (fi->pc);
172
173 insn = read_memory_integer (pc, 2);
174
c4deed18
SC
175 fi->leaf_function = 1;
176 fi->f_offset = 0;
177
9faacb92
SC
178 for (rn = 0; rn < NUM_REGS; rn++)
179 where[rn] = -1;
180
181 depth = 0;
182
183 /* Loop around examining the prologue insns, but give up
184 after 15 of them, since we're getting silly then */
185 while (pc < opc + 15 * 2)
186 {
187 /* See where the registers will be saved to */
188 if (IS_PUSH (insn))
189 {
190 pc += 2;
191 rn = GET_PUSHED_REG (insn);
192 where[rn] = depth;
193 insn = read_memory_integer (pc, 2);
194 depth += 4;
195 }
196 else if (IS_STS (insn))
197 {
198 pc += 2;
199 where[PR_REGNUM] = depth;
200 insn = read_memory_integer (pc, 2);
c4deed18
SC
201 /* If we're storing the pr then this isn't a leaf */
202 fi->leaf_function = 0;
9faacb92
SC
203 depth += 4;
204 }
c4deed18
SC
205 else if (IS_MOV_R3 (insn))
206 {
5f2f2809
SC
207 r3_val = (char) (insn & 0xff);
208 pc += 2;
c4deed18
SC
209 insn = read_memory_integer (pc, 2);
210 }
211 else if (IS_SHLL_R3 (insn))
212 {
5f2f2809
SC
213 r3_val <<= 1;
214 pc += 2;
c4deed18
SC
215 insn = read_memory_integer (pc, 2);
216 }
217 else if (IS_ADD_R3SP (insn))
218 {
219 depth += -r3_val;
5f2f2809 220 pc += 2;
c4deed18
SC
221 insn = read_memory_integer (pc, 2);
222 }
9faacb92
SC
223 else if (IS_ADD_SP (insn))
224 {
225 pc += 2;
226 depth += -((char) (insn & 0xff));
227 insn = read_memory_integer (pc, 2);
228 }
df14b38b
SC
229 else
230 break;
9faacb92
SC
231 }
232
233 /* Now we know how deep things are, we can work out their addresses */
234
235 for (rn = 0; rn < NUM_REGS; rn++)
236 {
237 if (where[rn] >= 0)
238 {
239 if (rn == FP_REGNUM)
240 have_fp = 1;
241
242 fsr->regs[rn] = fi->frame - where[rn] + depth - 4;
243 }
244 else
245 {
246 fsr->regs[rn] = 0;
247 }
248 }
249
250 if (have_fp)
251 {
9faacb92
SC
252 fsr->regs[SP_REGNUM] = read_memory_integer (fsr->regs[FP_REGNUM], 4);
253 }
254 else
255 {
256 fsr->regs[SP_REGNUM] = fi->frame - 4;
257 }
258
c4deed18 259 fi->f_offset = depth - where[FP_REGNUM] - 4;
9faacb92
SC
260 /* Work out the return pc - either from the saved pr or the pr
261 value */
5f2f2809 262
5c8ba017
SG
263 if (fsr->regs[PR_REGNUM])
264 fi->return_pc = read_memory_integer (fsr->regs[PR_REGNUM], 4);
265 else
266 fi->return_pc = read_register (PR_REGNUM);
9faacb92
SC
267}
268
269/* initialize the extra info saved in a FRAME */
270
271void
272init_extra_frame_info (fromleaf, fi)
273 int fromleaf;
274 struct frame_info *fi;
275{
276 struct frame_saved_regs dummy;
66d05e03 277
5c8ba017
SG
278 if (fi->next)
279 fi->pc = fi->next->return_pc;
280
9faacb92
SC
281 frame_find_saved_regs (fi, &dummy);
282}
283
284
285/* Discard from the stack the innermost frame,
286 restoring all saved registers. */
287
288void
289pop_frame ()
290{
669caa9c 291 register struct frame_info *frame = get_current_frame ();
9faacb92
SC
292 register CORE_ADDR fp;
293 register int regnum;
294 struct frame_saved_regs fsr;
9faacb92 295
669caa9c
SS
296 fp = FRAME_FP (frame);
297 get_frame_saved_regs (frame, &fsr);
9faacb92
SC
298
299 /* Copy regs from where they were saved in the frame */
300 for (regnum = 0; regnum < NUM_REGS; regnum++)
301 {
302 if (fsr.regs[regnum])
303 {
304 write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
305 }
306 }
307
5f2f2809 308 write_register (PC_REGNUM, frame->return_pc);
9faacb92
SC
309 write_register (SP_REGNUM, fp + 4);
310 flush_cached_frames ();
9faacb92 311}
edd01519 312
00dd4fd9
SS
313/* Command to set the processor type. */
314
315void
316sh_set_processor_type_command (args, from_tty)
317 char *args;
318 int from_tty;
319{
320 int i;
321 char *temp;
322
323 /* The `set' commands work by setting the value, then calling the hook,
324 so we let the general command modify a scratch location, then decide
325 here if we really want to modify the processor type. */
326 if (tmp_sh_processor_type == NULL || *tmp_sh_processor_type == '\0')
327 {
328 printf_unfiltered ("The known SH processor types are as follows:\n\n");
329 for (i = 0; sh_processor_type_table[i].name != NULL; ++i)
330 printf_unfiltered ("%s\n", sh_processor_type_table[i].name);
331
332 /* Restore the value. */
333 tmp_sh_processor_type = strsave (sh_processor_type);
334
335 return;
336 }
337
338 if (!sh_set_processor_type (tmp_sh_processor_type))
339 {
340 /* Restore to a valid value before erroring out. */
341 temp = tmp_sh_processor_type;
342 tmp_sh_processor_type = strsave (sh_processor_type);
343 error ("Unknown processor type `%s'.", temp);
344 }
345}
346
347static void
348sh_show_processor_type_command (args, from_tty)
349 char *args;
350 int from_tty;
351{
352}
353
354/* Modify the actual processor type. */
355
356int
357sh_set_processor_type (str)
358 char *str;
359{
360 int i, j;
361
362 if (str == NULL)
363 return 0;
364
365 for (i = 0; sh_processor_type_table[i].name != NULL; ++i)
366 {
367 if (strcasecmp (str, sh_processor_type_table[i].name) == 0)
368 {
369 sh_processor_type = str;
370
371 for (j = 0; j < NUM_REGS; ++j)
372 reg_names[j] = sh_processor_type_table[i].regnames[j];
373
374 return 1;
375 }
376 }
377
378 return 0;
379}
380
edd01519 381/* Print the registers in a form similar to the E7000 */
669caa9c 382
edd01519
SC
383static void
384show_regs (args, from_tty)
669caa9c
SS
385 char *args;
386 int from_tty;
edd01519 387{
5f2f2809
SC
388 printf_filtered ("PC=%08x SR=%08x PR=%08x MACH=%08x MACHL=%08x\n",
389 read_register (PC_REGNUM),
390 read_register (SR_REGNUM),
391 read_register (PR_REGNUM),
392 read_register (MACH_REGNUM),
393 read_register (MACL_REGNUM));
394
395 printf_filtered ("R0-R7 %08x %08x %08x %08x %08x %08x %08x %08x\n",
396 read_register (0),
397 read_register (1),
398 read_register (2),
399 read_register (3),
400 read_register (4),
401 read_register (5),
402 read_register (6),
403 read_register (7));
404 printf_filtered ("R8-R15 %08x %08x %08x %08x %08x %08x %08x %08x\n",
405 read_register (8),
406 read_register (9),
407 read_register (10),
408 read_register (11),
409 read_register (12),
410 read_register (13),
411 read_register (14),
412 read_register (15));
edd01519 413}
c853c90d 414\f
976bb0be 415void
df14b38b
SC
416_initialize_sh_tdep ()
417{
00dd4fd9
SS
418 struct cmd_list_element *c;
419
18b46e7c
SS
420 tm_print_insn = gdb_print_insn_sh;
421
00dd4fd9
SS
422 c = add_set_cmd ("processor", class_support, var_string_noescape,
423 (char *) &tmp_sh_processor_type,
424 "Set the type of SH processor in use.\n\
425Set this to be able to access processor-type-specific registers.\n\
426",
427 &setlist);
428 c->function.cfunc = sh_set_processor_type_command;
429 c = add_show_from_set (c, &showlist);
430 c->function.cfunc = sh_show_processor_type_command;
431
432 tmp_sh_processor_type = strsave (DEFAULT_SH_TYPE);
433 sh_set_processor_type_command (strsave (DEFAULT_SH_TYPE), 0);
434
5f2f2809 435 add_com ("regs", class_vars, show_regs, "Print all registers");
df14b38b 436}
This page took 0.212686 seconds and 4 git commands to generate.