xref: /openbsd-src/gnu/usr.bin/binutils/gdb/sh-tdep.c (revision 2f0504870622346ae2f69899daa9fe8a414692b5)
1b725ae77Skettenis /* Target-dependent code for Renesas Super-H, for GDB.
2b725ae77Skettenis    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3b725ae77Skettenis    2003, 2004 Free Software Foundation, Inc.
4e93f7393Sniklas 
5e93f7393Sniklas    This file is part of GDB.
6e93f7393Sniklas 
7e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
8e93f7393Sniklas    it under the terms of the GNU General Public License as published by
9e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
10e93f7393Sniklas    (at your option) any later version.
11e93f7393Sniklas 
12e93f7393Sniklas    This program is distributed in the hope that it will be useful,
13e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
14e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15e93f7393Sniklas    GNU General Public License for more details.
16e93f7393Sniklas 
17e93f7393Sniklas    You should have received a copy of the GNU General Public License
18e93f7393Sniklas    along with this program; if not, write to the Free Software
19b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
20b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
21e93f7393Sniklas 
22e93f7393Sniklas /*
23e93f7393Sniklas    Contributed by Steve Chamberlain
24e93f7393Sniklas    sac@cygnus.com
25e93f7393Sniklas  */
26e93f7393Sniklas 
27e93f7393Sniklas #include "defs.h"
28e93f7393Sniklas #include "frame.h"
29b725ae77Skettenis #include "frame-base.h"
30b725ae77Skettenis #include "frame-unwind.h"
31b725ae77Skettenis #include "dwarf2-frame.h"
32e93f7393Sniklas #include "symtab.h"
33e93f7393Sniklas #include "gdbtypes.h"
34e93f7393Sniklas #include "gdbcmd.h"
35e93f7393Sniklas #include "gdbcore.h"
36e93f7393Sniklas #include "value.h"
37e93f7393Sniklas #include "dis-asm.h"
38b725ae77Skettenis #include "inferior.h"
39b725ae77Skettenis #include "gdb_string.h"
40b725ae77Skettenis #include "gdb_assert.h"
41b725ae77Skettenis #include "arch-utils.h"
42b725ae77Skettenis #include "floatformat.h"
43b725ae77Skettenis #include "regcache.h"
44b725ae77Skettenis #include "doublest.h"
45b725ae77Skettenis #include "osabi.h"
46e93f7393Sniklas 
47b725ae77Skettenis #include "sh-tdep.h"
48e93f7393Sniklas 
49b725ae77Skettenis #include "elf-bfd.h"
50b725ae77Skettenis #include "solib-svr4.h"
51e93f7393Sniklas 
52b725ae77Skettenis /* sh flags */
53b725ae77Skettenis #include "elf/sh.h"
54b725ae77Skettenis /* registers numbers shared with the simulator */
55b725ae77Skettenis #include "gdb/sim-sh.h"
56e93f7393Sniklas 
57b725ae77Skettenis static void (*sh_show_regs) (void);
58e93f7393Sniklas 
5963addd46Skettenis #define SH_NUM_REGS 67
60e93f7393Sniklas 
61b725ae77Skettenis struct sh_frame_cache
62b725ae77Skettenis {
63b725ae77Skettenis   /* Base address.  */
64b725ae77Skettenis   CORE_ADDR base;
65b725ae77Skettenis   LONGEST sp_offset;
66b725ae77Skettenis   CORE_ADDR pc;
67e93f7393Sniklas 
68b725ae77Skettenis   /* Flag showing that a frame has been created in the prologue code. */
69b725ae77Skettenis   int uses_fp;
70e93f7393Sniklas 
71b725ae77Skettenis   /* Saved registers.  */
72b725ae77Skettenis   CORE_ADDR saved_regs[SH_NUM_REGS];
73b725ae77Skettenis   CORE_ADDR saved_sp;
74b725ae77Skettenis };
75e93f7393Sniklas 
76b725ae77Skettenis static const char *
sh_sh_register_name(int reg_nr)77b725ae77Skettenis sh_sh_register_name (int reg_nr)
78b725ae77Skettenis {
79b725ae77Skettenis   static char *register_names[] = {
80e93f7393Sniklas     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
81e93f7393Sniklas     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
82e93f7393Sniklas     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
83e93f7393Sniklas     "", "",
84e93f7393Sniklas     "", "", "", "", "", "", "", "",
85e93f7393Sniklas     "", "", "", "", "", "", "", "",
86e93f7393Sniklas     "", "",
87e93f7393Sniklas     "", "", "", "", "", "", "", "",
88e93f7393Sniklas     "", "", "", "", "", "", "", "",
8963addd46Skettenis     "", "", "", "", "", "", "", "",
90e93f7393Sniklas   };
91b725ae77Skettenis   if (reg_nr < 0)
92b725ae77Skettenis     return NULL;
93b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
94b725ae77Skettenis     return NULL;
95b725ae77Skettenis   return register_names[reg_nr];
96b725ae77Skettenis }
97e93f7393Sniklas 
98b725ae77Skettenis static const char *
sh_sh3_register_name(int reg_nr)99b725ae77Skettenis sh_sh3_register_name (int reg_nr)
100b725ae77Skettenis {
101b725ae77Skettenis   static char *register_names[] = {
102e93f7393Sniklas     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
103e93f7393Sniklas     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
104e93f7393Sniklas     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
105e93f7393Sniklas     "", "",
106e93f7393Sniklas     "", "", "", "", "", "", "", "",
107e93f7393Sniklas     "", "", "", "", "", "", "", "",
108e93f7393Sniklas     "ssr", "spc",
109e93f7393Sniklas     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
110e93f7393Sniklas     "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1"
11163addd46Skettenis     "", "", "", "", "", "", "", "",
112e93f7393Sniklas   };
113b725ae77Skettenis   if (reg_nr < 0)
114b725ae77Skettenis     return NULL;
115b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
116b725ae77Skettenis     return NULL;
117b725ae77Skettenis   return register_names[reg_nr];
118b725ae77Skettenis }
119e93f7393Sniklas 
120b725ae77Skettenis static const char *
sh_sh3e_register_name(int reg_nr)121b725ae77Skettenis sh_sh3e_register_name (int reg_nr)
122b725ae77Skettenis {
123b725ae77Skettenis   static char *register_names[] = {
124e93f7393Sniklas     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
125e93f7393Sniklas     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
126e93f7393Sniklas     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
127e93f7393Sniklas     "fpul", "fpscr",
128e93f7393Sniklas     "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
129e93f7393Sniklas     "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
130e93f7393Sniklas     "ssr", "spc",
131e93f7393Sniklas     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
132e93f7393Sniklas     "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
13363addd46Skettenis     "", "", "", "", "", "", "", "",
134e93f7393Sniklas   };
135b725ae77Skettenis   if (reg_nr < 0)
136b725ae77Skettenis     return NULL;
137b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
138b725ae77Skettenis     return NULL;
139b725ae77Skettenis   return register_names[reg_nr];
140b725ae77Skettenis }
141e93f7393Sniklas 
142b725ae77Skettenis static const char *
sh_sh2e_register_name(int reg_nr)143b725ae77Skettenis sh_sh2e_register_name (int reg_nr)
144b725ae77Skettenis {
145b725ae77Skettenis   static char *register_names[] = {
146b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
147b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
148b725ae77Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
149b725ae77Skettenis     "fpul", "fpscr",
150b725ae77Skettenis     "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
151b725ae77Skettenis     "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
152b725ae77Skettenis     "", "",
153b725ae77Skettenis     "", "", "", "", "", "", "", "",
154b725ae77Skettenis     "", "", "", "", "", "", "", "",
15563addd46Skettenis     "", "", "", "", "", "", "", "",
15663addd46Skettenis   };
15763addd46Skettenis   if (reg_nr < 0)
15863addd46Skettenis     return NULL;
15963addd46Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
16063addd46Skettenis     return NULL;
16163addd46Skettenis   return register_names[reg_nr];
16263addd46Skettenis }
16363addd46Skettenis 
164*2f050487Smiod #ifdef notyet
16563addd46Skettenis static const char *
sh_sh2a_register_name(int reg_nr)16663addd46Skettenis sh_sh2a_register_name (int reg_nr)
16763addd46Skettenis {
16863addd46Skettenis   static char *register_names[] = {
16963addd46Skettenis     /* general registers 0-15 */
17063addd46Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
17163addd46Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
17263addd46Skettenis     /* 16 - 22 */
17363addd46Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
17463addd46Skettenis     /* 23, 24 */
17563addd46Skettenis     "fpul", "fpscr",
17663addd46Skettenis     /* floating point registers 25 - 40 */
17763addd46Skettenis     "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
17863addd46Skettenis     "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
17963addd46Skettenis     /* 41, 42 */
18063addd46Skettenis     "", "",
18163addd46Skettenis     /* 43 - 62.  Banked registers.  The bank number used is determined by
18263addd46Skettenis        the bank register (63). */
18363addd46Skettenis     "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
18463addd46Skettenis     "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b",
18563addd46Skettenis     "machb", "ivnb", "prb", "gbrb", "maclb",
18663addd46Skettenis     /* 63: register bank number, not a real register but used to
18763addd46Skettenis        communicate the register bank currently get/set.  This register
18863addd46Skettenis        is hidden to the user, who manipulates it using the pseudo
18963addd46Skettenis        register called "bank" (67).  See below.  */
19063addd46Skettenis     "",
19163addd46Skettenis     /* 64 - 66 */
19263addd46Skettenis     "ibcr", "ibnr", "tbr",
19363addd46Skettenis     /* 67: register bank number, the user visible pseudo register.  */
19463addd46Skettenis     "bank",
19563addd46Skettenis     /* double precision (pseudo) 68 - 75 */
19663addd46Skettenis     "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
19763addd46Skettenis   };
19863addd46Skettenis   if (reg_nr < 0)
19963addd46Skettenis     return NULL;
20063addd46Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
20163addd46Skettenis     return NULL;
20263addd46Skettenis   return register_names[reg_nr];
20363addd46Skettenis }
20463addd46Skettenis 
20563addd46Skettenis static const char *
sh_sh2a_nofpu_register_name(int reg_nr)20663addd46Skettenis sh_sh2a_nofpu_register_name (int reg_nr)
20763addd46Skettenis {
20863addd46Skettenis   static char *register_names[] = {
20963addd46Skettenis     /* general registers 0-15 */
21063addd46Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
21163addd46Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
21263addd46Skettenis     /* 16 - 22 */
21363addd46Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
21463addd46Skettenis     /* 23, 24 */
21563addd46Skettenis     "", "",
21663addd46Skettenis     /* floating point registers 25 - 40 */
21763addd46Skettenis     "", "", "", "", "", "", "", "",
21863addd46Skettenis     "", "", "", "", "", "", "", "",
21963addd46Skettenis     /* 41, 42 */
22063addd46Skettenis     "", "",
22163addd46Skettenis     /* 43 - 62.  Banked registers.  The bank number used is determined by
22263addd46Skettenis        the bank register (63). */
22363addd46Skettenis     "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
22463addd46Skettenis     "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b",
22563addd46Skettenis     "machb", "ivnb", "prb", "gbrb", "maclb",
22663addd46Skettenis     /* 63: register bank number, not a real register but used to
22763addd46Skettenis        communicate the register bank currently get/set.  This register
22863addd46Skettenis        is hidden to the user, who manipulates it using the pseudo
22963addd46Skettenis        register called "bank" (67).  See below.  */
23063addd46Skettenis     "",
23163addd46Skettenis     /* 64 - 66 */
23263addd46Skettenis     "ibcr", "ibnr", "tbr",
23363addd46Skettenis     /* 67: register bank number, the user visible pseudo register.  */
23463addd46Skettenis     "bank",
23563addd46Skettenis     /* double precision (pseudo) 68 - 75 */
23663addd46Skettenis     "", "", "", "", "", "", "", "",
237e93f7393Sniklas   };
238b725ae77Skettenis   if (reg_nr < 0)
239b725ae77Skettenis     return NULL;
240b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
241b725ae77Skettenis     return NULL;
242b725ae77Skettenis   return register_names[reg_nr];
243b725ae77Skettenis }
244*2f050487Smiod #endif
245b725ae77Skettenis 
246b725ae77Skettenis static const char *
sh_sh_dsp_register_name(int reg_nr)247b725ae77Skettenis sh_sh_dsp_register_name (int reg_nr)
248b725ae77Skettenis {
249b725ae77Skettenis   static char *register_names[] = {
250b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
251b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
252b725ae77Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
253b725ae77Skettenis     "", "dsr",
254b725ae77Skettenis     "a0g", "a0", "a1g", "a1", "m0", "m1", "x0", "x1",
255b725ae77Skettenis     "y0", "y1", "", "", "", "", "", "mod",
256b725ae77Skettenis     "", "",
257b725ae77Skettenis     "rs", "re", "", "", "", "", "", "",
258b725ae77Skettenis     "", "", "", "", "", "", "", "",
25963addd46Skettenis     "", "", "", "", "", "", "", "",
260b725ae77Skettenis   };
261b725ae77Skettenis   if (reg_nr < 0)
262b725ae77Skettenis     return NULL;
263b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
264b725ae77Skettenis     return NULL;
265b725ae77Skettenis   return register_names[reg_nr];
266b725ae77Skettenis }
267b725ae77Skettenis 
268b725ae77Skettenis static const char *
sh_sh3_dsp_register_name(int reg_nr)269b725ae77Skettenis sh_sh3_dsp_register_name (int reg_nr)
270b725ae77Skettenis {
271b725ae77Skettenis   static char *register_names[] = {
272b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
273b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
274b725ae77Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
275b725ae77Skettenis     "", "dsr",
276b725ae77Skettenis     "a0g", "a0", "a1g", "a1", "m0", "m1", "x0", "x1",
277b725ae77Skettenis     "y0", "y1", "", "", "", "", "", "mod",
278b725ae77Skettenis     "ssr", "spc",
279b725ae77Skettenis     "rs", "re", "", "", "", "", "", "",
280b725ae77Skettenis     "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
281b725ae77Skettenis     "", "", "", "", "", "", "", "",
28263addd46Skettenis     "", "", "", "", "", "", "", "",
283b725ae77Skettenis   };
284b725ae77Skettenis   if (reg_nr < 0)
285b725ae77Skettenis     return NULL;
286b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
287b725ae77Skettenis     return NULL;
288b725ae77Skettenis   return register_names[reg_nr];
289b725ae77Skettenis }
290b725ae77Skettenis 
291b725ae77Skettenis static const char *
sh_sh4_register_name(int reg_nr)292b725ae77Skettenis sh_sh4_register_name (int reg_nr)
293b725ae77Skettenis {
294b725ae77Skettenis   static char *register_names[] = {
295b725ae77Skettenis     /* general registers 0-15 */
296b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
297b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
298b725ae77Skettenis     /* 16 - 22 */
299b725ae77Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
300b725ae77Skettenis     /* 23, 24 */
301b725ae77Skettenis     "fpul", "fpscr",
302b725ae77Skettenis     /* floating point registers 25 - 40 */
303b725ae77Skettenis     "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
304b725ae77Skettenis     "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
305b725ae77Skettenis     /* 41, 42 */
306b725ae77Skettenis     "ssr", "spc",
307b725ae77Skettenis     /* bank 0 43 - 50 */
308b725ae77Skettenis     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
309b725ae77Skettenis     /* bank 1 51 - 58 */
310b725ae77Skettenis     "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
31163addd46Skettenis     "", "", "", "", "", "", "", "",
31263addd46Skettenis     /* pseudo bank register. */
31363addd46Skettenis     "",
314b725ae77Skettenis     /* double precision (pseudo) 59 - 66 */
315b725ae77Skettenis     "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
316b725ae77Skettenis     /* vectors (pseudo) 67 - 70 */
317b725ae77Skettenis     "fv0", "fv4", "fv8", "fv12",
318b725ae77Skettenis     /* FIXME: missing XF 71 - 86 */
319b725ae77Skettenis     /* FIXME: missing XD 87 - 94 */
320b725ae77Skettenis   };
321b725ae77Skettenis   if (reg_nr < 0)
322b725ae77Skettenis     return NULL;
323b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
324b725ae77Skettenis     return NULL;
325b725ae77Skettenis   return register_names[reg_nr];
326b725ae77Skettenis }
327b725ae77Skettenis 
328b725ae77Skettenis static const char *
sh_sh4_nofpu_register_name(int reg_nr)329b725ae77Skettenis sh_sh4_nofpu_register_name (int reg_nr)
330b725ae77Skettenis {
331b725ae77Skettenis   static char *register_names[] = {
332b725ae77Skettenis     /* general registers 0-15 */
333b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
334b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
335b725ae77Skettenis     /* 16 - 22 */
336b725ae77Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
337b725ae77Skettenis     /* 23, 24 */
338b725ae77Skettenis     "", "",
339b725ae77Skettenis     /* floating point registers 25 - 40 -- not for nofpu target */
340b725ae77Skettenis     "", "", "", "", "", "", "", "",
341b725ae77Skettenis     "", "", "", "", "", "", "", "",
342b725ae77Skettenis     /* 41, 42 */
343b725ae77Skettenis     "ssr", "spc",
344b725ae77Skettenis     /* bank 0 43 - 50 */
345b725ae77Skettenis     "r0b0", "r1b0", "r2b0", "r3b0", "r4b0", "r5b0", "r6b0", "r7b0",
346b725ae77Skettenis     /* bank 1 51 - 58 */
347b725ae77Skettenis     "r0b1", "r1b1", "r2b1", "r3b1", "r4b1", "r5b1", "r6b1", "r7b1",
34863addd46Skettenis     "", "", "", "", "", "", "", "",
34963addd46Skettenis     /* pseudo bank register. */
35063addd46Skettenis     "",
351b725ae77Skettenis     /* double precision (pseudo) 59 - 66 -- not for nofpu target */
352b725ae77Skettenis     "", "", "", "", "", "", "", "",
353b725ae77Skettenis     /* vectors (pseudo) 67 - 70 -- not for nofpu target */
354b725ae77Skettenis     "", "", "", "",
355b725ae77Skettenis   };
356b725ae77Skettenis   if (reg_nr < 0)
357b725ae77Skettenis     return NULL;
358b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
359b725ae77Skettenis     return NULL;
360b725ae77Skettenis   return register_names[reg_nr];
361b725ae77Skettenis }
362b725ae77Skettenis 
363b725ae77Skettenis static const char *
sh_sh4al_dsp_register_name(int reg_nr)364b725ae77Skettenis sh_sh4al_dsp_register_name (int reg_nr)
365b725ae77Skettenis {
366b725ae77Skettenis   static char *register_names[] = {
367b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
368b725ae77Skettenis     "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
369b725ae77Skettenis     "pc", "pr", "gbr", "vbr", "mach", "macl", "sr",
370b725ae77Skettenis     "", "dsr",
371b725ae77Skettenis     "a0g", "a0", "a1g", "a1", "m0", "m1", "x0", "x1",
372b725ae77Skettenis     "y0", "y1", "", "", "", "", "", "mod",
373b725ae77Skettenis     "ssr", "spc",
374b725ae77Skettenis     "rs", "re", "", "", "", "", "", "",
375b725ae77Skettenis     "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
376b725ae77Skettenis     "", "", "", "", "", "", "", "",
37763addd46Skettenis     "", "", "", "", "", "", "", "",
378b725ae77Skettenis   };
379b725ae77Skettenis   if (reg_nr < 0)
380b725ae77Skettenis     return NULL;
381b725ae77Skettenis   if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
382b725ae77Skettenis     return NULL;
383b725ae77Skettenis   return register_names[reg_nr];
384b725ae77Skettenis }
385b725ae77Skettenis 
386b725ae77Skettenis static const unsigned char *
sh_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)387b725ae77Skettenis sh_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
388b725ae77Skettenis {
389b725ae77Skettenis   /* 0xc3c3 is trapa #c3, and it works in big and little endian modes */
390b725ae77Skettenis   static unsigned char breakpoint[] = { 0xc3, 0xc3 };
391b725ae77Skettenis 
392b725ae77Skettenis   *lenptr = sizeof (breakpoint);
393b725ae77Skettenis   return breakpoint;
394b725ae77Skettenis }
395e93f7393Sniklas 
396e93f7393Sniklas /* Prologue looks like
397b725ae77Skettenis    mov.l	r14,@-r15
398b725ae77Skettenis    sts.l	pr,@-r15
399b725ae77Skettenis    mov.l	<regs>,@-r15
400b725ae77Skettenis    sub		<room_for_loca_vars>,r15
401b725ae77Skettenis    mov		r15,r14
402b725ae77Skettenis 
403b725ae77Skettenis    Actually it can be more complicated than this but that's it, basically.
404e93f7393Sniklas  */
405e93f7393Sniklas 
406b725ae77Skettenis #define GET_SOURCE_REG(x)  	(((x) >> 4) & 0xf)
407b725ae77Skettenis #define GET_TARGET_REG(x)  	(((x) >> 8) & 0xf)
408b725ae77Skettenis 
409b725ae77Skettenis /* JSR @Rm         0100mmmm00001011 */
410b725ae77Skettenis #define IS_JSR(x)		(((x) & 0xf0ff) == 0x400b)
411b725ae77Skettenis 
412b725ae77Skettenis /* STS.L PR,@-r15  0100111100100010
413b725ae77Skettenis    r15-4-->r15, PR-->(r15) */
414e93f7393Sniklas #define IS_STS(x)  		((x) == 0x4f22)
415b725ae77Skettenis 
41663addd46Skettenis /* STS.L MACL,@-r15  0100111100010010
41763addd46Skettenis    r15-4-->r15, MACL-->(r15) */
41863addd46Skettenis #define IS_MACL_STS(x)  	((x) == 0x4f12)
41963addd46Skettenis 
420b725ae77Skettenis /* MOV.L Rm,@-r15  00101111mmmm0110
421b725ae77Skettenis    r15-4-->r15, Rm-->(R15) */
422e93f7393Sniklas #define IS_PUSH(x) 		(((x) & 0xff0f) == 0x2f06)
423b725ae77Skettenis 
424b725ae77Skettenis /* MOV r15,r14     0110111011110011
425b725ae77Skettenis    r15-->r14  */
426e93f7393Sniklas #define IS_MOV_SP_FP(x)  	((x) == 0x6ef3)
427b725ae77Skettenis 
428b725ae77Skettenis /* ADD #imm,r15    01111111iiiiiiii
429b725ae77Skettenis    r15+imm-->r15 */
430b725ae77Skettenis #define IS_ADD_IMM_SP(x) 	(((x) & 0xff00) == 0x7f00)
431b725ae77Skettenis 
432e93f7393Sniklas #define IS_MOV_R3(x) 		(((x) & 0xff00) == 0x1a00)
433e93f7393Sniklas #define IS_SHLL_R3(x)		((x) == 0x4300)
434b725ae77Skettenis 
435b725ae77Skettenis /* ADD r3,r15      0011111100111100
436b725ae77Skettenis    r15+r3-->r15 */
437e93f7393Sniklas #define IS_ADD_R3SP(x)		((x) == 0x3f3c)
438e93f7393Sniklas 
439b725ae77Skettenis /* FMOV.S FRm,@-Rn  Rn-4-->Rn, FRm-->(Rn)     1111nnnnmmmm1011
440b725ae77Skettenis    FMOV DRm,@-Rn    Rn-8-->Rn, DRm-->(Rn)     1111nnnnmmm01011
441b725ae77Skettenis    FMOV XDm,@-Rn    Rn-8-->Rn, XDm-->(Rn)     1111nnnnmmm11011 */
442b725ae77Skettenis /* CV, 2003-08-28: Only suitable with Rn == SP, therefore name changed to
443b725ae77Skettenis 		   make this entirely clear. */
444b725ae77Skettenis /* #define IS_FMOV(x)		(((x) & 0xf00f) == 0xf00b) */
445b725ae77Skettenis #define IS_FPUSH(x)		(((x) & 0xff0f) == 0xff0b)
446e93f7393Sniklas 
447b725ae77Skettenis /* MOV Rm,Rn          Rm-->Rn        0110nnnnmmmm0011  4 <= m <= 7 */
448b725ae77Skettenis #define IS_MOV_ARG_TO_REG(x) \
449b725ae77Skettenis 	(((x) & 0xf00f) == 0x6003 && \
450b725ae77Skettenis 	 ((x) & 0x00f0) >= 0x0040 && \
451b725ae77Skettenis 	 ((x) & 0x00f0) <= 0x0070)
452b725ae77Skettenis /* MOV.L Rm,@Rn               0010nnnnmmmm0010  n = 14, 4 <= m <= 7 */
453b725ae77Skettenis #define IS_MOV_ARG_TO_IND_R14(x) \
454b725ae77Skettenis 	(((x) & 0xff0f) == 0x2e02 && \
455b725ae77Skettenis 	 ((x) & 0x00f0) >= 0x0040 && \
456b725ae77Skettenis 	 ((x) & 0x00f0) <= 0x0070)
457b725ae77Skettenis /* MOV.L Rm,@(disp*4,Rn)      00011110mmmmdddd  n = 14, 4 <= m <= 7 */
458b725ae77Skettenis #define IS_MOV_ARG_TO_IND_R14_WITH_DISP(x) \
459b725ae77Skettenis 	(((x) & 0xff00) == 0x1e00 && \
460b725ae77Skettenis 	 ((x) & 0x00f0) >= 0x0040 && \
461b725ae77Skettenis 	 ((x) & 0x00f0) <= 0x0070)
462e93f7393Sniklas 
463b725ae77Skettenis /* MOV.W @(disp*2,PC),Rn      1001nnnndddddddd */
464b725ae77Skettenis #define IS_MOVW_PCREL_TO_REG(x)	(((x) & 0xf000) == 0x9000)
465b725ae77Skettenis /* MOV.L @(disp*4,PC),Rn      1101nnnndddddddd */
466b725ae77Skettenis #define IS_MOVL_PCREL_TO_REG(x)	(((x) & 0xf000) == 0xd000)
46763addd46Skettenis /* MOVI20 #imm20,Rn           0000nnnniiii0000 */
46863addd46Skettenis #define IS_MOVI20(x)		(((x) & 0xf00f) == 0x0000)
469b725ae77Skettenis /* SUB Rn,R15                 00111111nnnn1000 */
470b725ae77Skettenis #define IS_SUB_REG_FROM_SP(x)	(((x) & 0xff0f) == 0x3f08)
471e93f7393Sniklas 
472b725ae77Skettenis #define FPSCR_SZ		(1 << 20)
473b725ae77Skettenis 
474b725ae77Skettenis /* The following instructions are used for epilogue testing. */
475b725ae77Skettenis #define IS_RESTORE_FP(x)	((x) == 0x6ef6)
476b725ae77Skettenis #define IS_RTS(x)		((x) == 0x000b)
477b725ae77Skettenis #define IS_LDS(x)  		((x) == 0x4f26)
47863addd46Skettenis #define IS_MACL_LDS(x)  	((x) == 0x4f16)
479b725ae77Skettenis #define IS_MOV_FP_SP(x)  	((x) == 0x6fe3)
480b725ae77Skettenis #define IS_ADD_REG_TO_FP(x)	(((x) & 0xff0f) == 0x3e0c)
481b725ae77Skettenis #define IS_ADD_IMM_FP(x) 	(((x) & 0xff00) == 0x7e00)
482e93f7393Sniklas 
483e93f7393Sniklas /* Disassemble an instruction.  */
484b725ae77Skettenis static int
gdb_print_insn_sh(bfd_vma memaddr,disassemble_info * info)485b725ae77Skettenis gdb_print_insn_sh (bfd_vma memaddr, disassemble_info * info)
486e93f7393Sniklas {
487b725ae77Skettenis   info->endian = TARGET_BYTE_ORDER;
488e93f7393Sniklas   return print_insn_sh (memaddr, info);
489e93f7393Sniklas }
490e93f7393Sniklas 
491b725ae77Skettenis static CORE_ADDR
sh_analyze_prologue(CORE_ADDR pc,CORE_ADDR current_pc,struct sh_frame_cache * cache)492b725ae77Skettenis sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc,
493b725ae77Skettenis 		     struct sh_frame_cache *cache)
494e93f7393Sniklas {
495b725ae77Skettenis   ULONGEST inst;
496b725ae77Skettenis   CORE_ADDR opc;
497b725ae77Skettenis   int offset;
498b725ae77Skettenis   int sav_offset = 0;
499e93f7393Sniklas   int r3_val = 0;
500b725ae77Skettenis   int reg, sav_reg = -1;
501e93f7393Sniklas 
502b725ae77Skettenis   if (pc >= current_pc)
503b725ae77Skettenis     return current_pc;
504e93f7393Sniklas 
505b725ae77Skettenis   cache->uses_fp = 0;
506b725ae77Skettenis   for (opc = pc + (2 * 28); pc < opc; pc += 2)
507e93f7393Sniklas     {
508b725ae77Skettenis       inst = read_memory_unsigned_integer (pc, 2);
509e93f7393Sniklas       /* See where the registers will be saved to */
510b725ae77Skettenis       if (IS_PUSH (inst))
511e93f7393Sniklas 	{
512b725ae77Skettenis 	  cache->saved_regs[GET_SOURCE_REG (inst)] = cache->sp_offset;
513b725ae77Skettenis 	  cache->sp_offset += 4;
514e93f7393Sniklas 	}
515b725ae77Skettenis       else if (IS_STS (inst))
516e93f7393Sniklas 	{
517b725ae77Skettenis 	  cache->saved_regs[PR_REGNUM] = cache->sp_offset;
518b725ae77Skettenis 	  cache->sp_offset += 4;
519e93f7393Sniklas 	}
52063addd46Skettenis       else if (IS_MACL_STS (inst))
52163addd46Skettenis 	{
52263addd46Skettenis 	  cache->saved_regs[MACL_REGNUM] = cache->sp_offset;
52363addd46Skettenis 	  cache->sp_offset += 4;
52463addd46Skettenis 	}
525b725ae77Skettenis       else if (IS_MOV_R3 (inst))
526e93f7393Sniklas 	{
527b725ae77Skettenis 	  r3_val = ((inst & 0xff) ^ 0x80) - 0x80;
528e93f7393Sniklas 	}
529b725ae77Skettenis       else if (IS_SHLL_R3 (inst))
530e93f7393Sniklas 	{
531e93f7393Sniklas 	  r3_val <<= 1;
532e93f7393Sniklas 	}
533b725ae77Skettenis       else if (IS_ADD_R3SP (inst))
534e93f7393Sniklas 	{
535b725ae77Skettenis 	  cache->sp_offset += -r3_val;
536e93f7393Sniklas 	}
537b725ae77Skettenis       else if (IS_ADD_IMM_SP (inst))
538e93f7393Sniklas 	{
539b725ae77Skettenis 	  offset = ((inst & 0xff) ^ 0x80) - 0x80;
540b725ae77Skettenis 	  cache->sp_offset -= offset;
541e93f7393Sniklas 	}
542b725ae77Skettenis       else if (IS_MOVW_PCREL_TO_REG (inst))
543b725ae77Skettenis 	{
544b725ae77Skettenis 	  if (sav_reg < 0)
545b725ae77Skettenis 	    {
546b725ae77Skettenis 	      reg = GET_TARGET_REG (inst);
547b725ae77Skettenis 	      if (reg < 14)
548b725ae77Skettenis 		{
549b725ae77Skettenis 		  sav_reg = reg;
55063addd46Skettenis 		  offset = (inst & 0xff) << 1;
551b725ae77Skettenis 		  sav_offset =
55263addd46Skettenis 		    read_memory_integer ((pc + 4) + offset, 2);
553b725ae77Skettenis 		}
554b725ae77Skettenis 	    }
555b725ae77Skettenis 	}
556b725ae77Skettenis       else if (IS_MOVL_PCREL_TO_REG (inst))
557b725ae77Skettenis 	{
558b725ae77Skettenis 	  if (sav_reg < 0)
559b725ae77Skettenis 	    {
56063addd46Skettenis 	      reg = GET_TARGET_REG (inst);
561b725ae77Skettenis 	      if (reg < 14)
562b725ae77Skettenis 		{
563b725ae77Skettenis 		  sav_reg = reg;
56463addd46Skettenis 		  offset = (inst & 0xff) << 2;
565b725ae77Skettenis 		  sav_offset =
56663addd46Skettenis 		    read_memory_integer (((pc & 0xfffffffc) + 4) + offset, 4);
56763addd46Skettenis 		}
56863addd46Skettenis 	    }
56963addd46Skettenis 	}
57063addd46Skettenis       else if (IS_MOVI20 (inst))
57163addd46Skettenis         {
57263addd46Skettenis 	  if (sav_reg < 0)
57363addd46Skettenis 	    {
57463addd46Skettenis 	      reg = GET_TARGET_REG (inst);
57563addd46Skettenis 	      if (reg < 14)
57663addd46Skettenis 	        {
57763addd46Skettenis 		  sav_reg = reg;
57863addd46Skettenis 		  sav_offset = GET_SOURCE_REG (inst) << 16;
57963addd46Skettenis 		  /* MOVI20 is a 32 bit instruction! */
58063addd46Skettenis 		  pc += 2;
58163addd46Skettenis 		  sav_offset |= read_memory_unsigned_integer (pc, 2);
58263addd46Skettenis 		  /* Now sav_offset contains an unsigned 20 bit value.
58363addd46Skettenis 		     It must still get sign extended.  */
58463addd46Skettenis 		  if (sav_offset & 0x00080000)
58563addd46Skettenis 		    sav_offset |= 0xfff00000;
586b725ae77Skettenis 		}
587b725ae77Skettenis 	    }
588b725ae77Skettenis 	}
589b725ae77Skettenis       else if (IS_SUB_REG_FROM_SP (inst))
590b725ae77Skettenis 	{
591b725ae77Skettenis 	  reg = GET_SOURCE_REG (inst);
592b725ae77Skettenis 	  if (sav_reg > 0 && reg == sav_reg)
593b725ae77Skettenis 	    {
594b725ae77Skettenis 	      sav_reg = -1;
595b725ae77Skettenis 	    }
596b725ae77Skettenis 	  cache->sp_offset += sav_offset;
597b725ae77Skettenis 	}
598b725ae77Skettenis       else if (IS_FPUSH (inst))
599b725ae77Skettenis 	{
600b725ae77Skettenis 	  if (read_register (FPSCR_REGNUM) & FPSCR_SZ)
601b725ae77Skettenis 	    {
602b725ae77Skettenis 	      cache->sp_offset += 8;
603b725ae77Skettenis 	    }
604b725ae77Skettenis 	  else
605b725ae77Skettenis 	    {
606b725ae77Skettenis 	      cache->sp_offset += 4;
607b725ae77Skettenis 	    }
608b725ae77Skettenis 	}
609b725ae77Skettenis       else if (IS_MOV_SP_FP (inst))
610b725ae77Skettenis 	{
611b725ae77Skettenis 	  cache->uses_fp = 1;
612b725ae77Skettenis 	  /* At this point, only allow argument register moves to other
613b725ae77Skettenis 	     registers or argument register moves to @(X,fp) which are
614b725ae77Skettenis 	     moving the register arguments onto the stack area allocated
615b725ae77Skettenis 	     by a former add somenumber to SP call.  Don't allow moving
616b725ae77Skettenis 	     to an fp indirect address above fp + cache->sp_offset. */
617b725ae77Skettenis 	  pc += 2;
618b725ae77Skettenis 	  for (opc = pc + 12; pc < opc; pc += 2)
619b725ae77Skettenis 	    {
620b725ae77Skettenis 	      inst = read_memory_integer (pc, 2);
621b725ae77Skettenis 	      if (IS_MOV_ARG_TO_IND_R14 (inst))
622b725ae77Skettenis 		{
623b725ae77Skettenis 		  reg = GET_SOURCE_REG (inst);
624b725ae77Skettenis 		  if (cache->sp_offset > 0)
625b725ae77Skettenis 		    cache->saved_regs[reg] = cache->sp_offset;
626b725ae77Skettenis 		}
627b725ae77Skettenis 	      else if (IS_MOV_ARG_TO_IND_R14_WITH_DISP (inst))
628b725ae77Skettenis 		{
629b725ae77Skettenis 		  reg = GET_SOURCE_REG (inst);
630b725ae77Skettenis 		  offset = (inst & 0xf) * 4;
631b725ae77Skettenis 		  if (cache->sp_offset > offset)
632b725ae77Skettenis 		    cache->saved_regs[reg] = cache->sp_offset - offset;
633b725ae77Skettenis 		}
634b725ae77Skettenis 	      else if (IS_MOV_ARG_TO_REG (inst))
635b725ae77Skettenis 		continue;
636e93f7393Sniklas 	      else
637e93f7393Sniklas 		break;
638e93f7393Sniklas 	    }
639b725ae77Skettenis 	  break;
640e93f7393Sniklas 	}
641b725ae77Skettenis       else if (IS_JSR (inst))
642b725ae77Skettenis 	{
643b725ae77Skettenis 	  /* We have found a jsr that has been scheduled into the prologue.
644b725ae77Skettenis 	     If we continue the scan and return a pc someplace after this,
645b725ae77Skettenis 	     then setting a breakpoint on this function will cause it to
646b725ae77Skettenis 	     appear to be called after the function it is calling via the
647b725ae77Skettenis 	     jsr, which will be very confusing.  Most likely the next
648b725ae77Skettenis 	     instruction is going to be IS_MOV_SP_FP in the delay slot.  If
649b725ae77Skettenis 	     so, note that before returning the current pc. */
650b725ae77Skettenis 	  inst = read_memory_integer (pc + 2, 2);
651b725ae77Skettenis 	  if (IS_MOV_SP_FP (inst))
652b725ae77Skettenis 	    cache->uses_fp = 1;
653b725ae77Skettenis 	  break;
654b725ae77Skettenis 	}
655b725ae77Skettenis #if 0				/* This used to just stop when it found an instruction that
656b725ae77Skettenis 				   was not considered part of the prologue.  Now, we just
657b725ae77Skettenis 				   keep going looking for likely instructions. */
658e93f7393Sniklas       else
659b725ae77Skettenis 	break;
660b725ae77Skettenis #endif
661b725ae77Skettenis     }
662b725ae77Skettenis 
663b725ae77Skettenis   return pc;
664b725ae77Skettenis }
665b725ae77Skettenis 
666b725ae77Skettenis /* Skip any prologue before the guts of a function */
667b725ae77Skettenis 
668b725ae77Skettenis /* Skip the prologue using the debug information. If this fails we'll
669b725ae77Skettenis    fall back on the 'guess' method below. */
670b725ae77Skettenis static CORE_ADDR
after_prologue(CORE_ADDR pc)671b725ae77Skettenis after_prologue (CORE_ADDR pc)
672e93f7393Sniklas {
673b725ae77Skettenis   struct symtab_and_line sal;
674b725ae77Skettenis   CORE_ADDR func_addr, func_end;
675e93f7393Sniklas 
676b725ae77Skettenis   /* If we can not find the symbol in the partial symbol table, then
677b725ae77Skettenis      there is no hope we can determine the function's start address
678b725ae77Skettenis      with this code.  */
679b725ae77Skettenis   if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
680e93f7393Sniklas     return 0;
681e93f7393Sniklas 
682b725ae77Skettenis   /* Get the line associated with FUNC_ADDR.  */
683b725ae77Skettenis   sal = find_pc_line (func_addr, 0);
684e93f7393Sniklas 
685b725ae77Skettenis   /* There are only two cases to consider.  First, the end of the source line
686b725ae77Skettenis      is within the function bounds.  In that case we return the end of the
687b725ae77Skettenis      source line.  Second is the end of the source line extends beyond the
688b725ae77Skettenis      bounds of the current function.  We need to use the slow code to
689b725ae77Skettenis      examine instructions in that case.  */
690b725ae77Skettenis   if (sal.end < func_end)
691b725ae77Skettenis     return sal.end;
692b725ae77Skettenis   else
693b725ae77Skettenis     return 0;
694b725ae77Skettenis }
695e93f7393Sniklas 
696b725ae77Skettenis static CORE_ADDR
sh_skip_prologue(CORE_ADDR start_pc)697b725ae77Skettenis sh_skip_prologue (CORE_ADDR start_pc)
698b725ae77Skettenis {
699b725ae77Skettenis   CORE_ADDR pc;
700b725ae77Skettenis   struct sh_frame_cache cache;
701b725ae77Skettenis 
702b725ae77Skettenis   /* See if we can determine the end of the prologue via the symbol table.
703b725ae77Skettenis      If so, then return either PC, or the PC after the prologue, whichever
704b725ae77Skettenis      is greater.  */
705b725ae77Skettenis   pc = after_prologue (start_pc);
706b725ae77Skettenis 
707b725ae77Skettenis   /* If after_prologue returned a useful address, then use it.  Else
708b725ae77Skettenis      fall back on the instruction skipping code. */
709b725ae77Skettenis   if (pc)
710b725ae77Skettenis     return max (pc, start_pc);
711b725ae77Skettenis 
712b725ae77Skettenis   cache.sp_offset = -4;
713b725ae77Skettenis   pc = sh_analyze_prologue (start_pc, (CORE_ADDR) -1, &cache);
714b725ae77Skettenis   if (!cache.uses_fp)
715b725ae77Skettenis     return start_pc;
716b725ae77Skettenis 
717b725ae77Skettenis   return pc;
718b725ae77Skettenis }
719b725ae77Skettenis 
720b725ae77Skettenis /* The ABI says:
721b725ae77Skettenis 
722b725ae77Skettenis    Aggregate types not bigger than 8 bytes that have the same size and
723b725ae77Skettenis    alignment as one of the integer scalar types are returned in the
724b725ae77Skettenis    same registers as the integer type they match.
725b725ae77Skettenis 
726b725ae77Skettenis    For example, a 2-byte aligned structure with size 2 bytes has the
727b725ae77Skettenis    same size and alignment as a short int, and will be returned in R0.
728b725ae77Skettenis    A 4-byte aligned structure with size 8 bytes has the same size and
729b725ae77Skettenis    alignment as a long long int, and will be returned in R0 and R1.
730b725ae77Skettenis 
731b725ae77Skettenis    When an aggregate type is returned in R0 and R1, R0 contains the
732b725ae77Skettenis    first four bytes of the aggregate, and R1 contains the
733b725ae77Skettenis    remainder. If the size of the aggregate type is not a multiple of 4
734b725ae77Skettenis    bytes, the aggregate is tail-padded up to a multiple of 4
735b725ae77Skettenis    bytes. The value of the padding is undefined. For little-endian
736b725ae77Skettenis    targets the padding will appear at the most significant end of the
737b725ae77Skettenis    last element, for big-endian targets the padding appears at the
738b725ae77Skettenis    least significant end of the last element.
739b725ae77Skettenis 
740b725ae77Skettenis    All other aggregate types are returned by address. The caller
741b725ae77Skettenis    function passes the address of an area large enough to hold the
742b725ae77Skettenis    aggregate value in R2. The called function stores the result in
743b725ae77Skettenis    this location.
744b725ae77Skettenis 
745b725ae77Skettenis    To reiterate, structs smaller than 8 bytes could also be returned
746b725ae77Skettenis    in memory, if they don't pass the "same size and alignment as an
747b725ae77Skettenis    integer type" rule.
748b725ae77Skettenis 
749b725ae77Skettenis    For example, in
750b725ae77Skettenis 
751b725ae77Skettenis    struct s { char c[3]; } wibble;
752b725ae77Skettenis    struct s foo(void) {  return wibble; }
753b725ae77Skettenis 
754b725ae77Skettenis    the return value from foo() will be in memory, not
755b725ae77Skettenis    in R0, because there is no 3-byte integer type.
756b725ae77Skettenis 
757b725ae77Skettenis    Similarly, in
758b725ae77Skettenis 
759b725ae77Skettenis    struct s { char c[2]; } wibble;
760b725ae77Skettenis    struct s foo(void) {  return wibble; }
761b725ae77Skettenis 
762b725ae77Skettenis    because a struct containing two chars has alignment 1, that matches
763b725ae77Skettenis    type char, but size 2, that matches type short.  There's no integer
764b725ae77Skettenis    type that has alignment 1 and size 2, so the struct is returned in
765b725ae77Skettenis    memory.
766b725ae77Skettenis 
767b725ae77Skettenis */
768b725ae77Skettenis 
769b725ae77Skettenis static int
sh_use_struct_convention(int gcc_p,struct type * type)770b725ae77Skettenis sh_use_struct_convention (int gcc_p, struct type *type)
771b725ae77Skettenis {
772b725ae77Skettenis   int len = TYPE_LENGTH (type);
773b725ae77Skettenis   int nelem = TYPE_NFIELDS (type);
774b725ae77Skettenis 
775b725ae77Skettenis   /* Non-power of 2 length types and types bigger than 8 bytes (which don't
776b725ae77Skettenis      fit in two registers anyway) use struct convention.  */
777b725ae77Skettenis   if (len != 1 && len != 2 && len != 4 && len != 8)
778b725ae77Skettenis     return 1;
779b725ae77Skettenis 
780b725ae77Skettenis   /* Scalar types and aggregate types with exactly one field are aligned
781b725ae77Skettenis      by definition.  They are returned in registers.  */
782b725ae77Skettenis   if (nelem <= 1)
783b725ae77Skettenis     return 0;
784b725ae77Skettenis 
785b725ae77Skettenis   /* If the first field in the aggregate has the same length as the entire
786b725ae77Skettenis      aggregate type, the type is returned in registers.  */
787b725ae77Skettenis   if (TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == len)
788b725ae77Skettenis     return 0;
789b725ae77Skettenis 
790b725ae77Skettenis   /* If the size of the aggregate is 8 bytes and the first field is
791b725ae77Skettenis      of size 4 bytes its alignment is equal to long long's alignment,
792b725ae77Skettenis      so it's returned in registers.  */
793b725ae77Skettenis   if (len == 8 && TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == 4)
794b725ae77Skettenis     return 0;
795b725ae77Skettenis 
796b725ae77Skettenis   /* Otherwise use struct convention.  */
797e93f7393Sniklas   return 1;
798e93f7393Sniklas }
799b725ae77Skettenis 
800b725ae77Skettenis /* Extract from an array REGBUF containing the (raw) register state
801b725ae77Skettenis    the address in which a function should return its structure value,
802b725ae77Skettenis    as a CORE_ADDR (or an expression that can be used as one).  */
803b725ae77Skettenis static CORE_ADDR
sh_extract_struct_value_address(struct regcache * regcache)804b725ae77Skettenis sh_extract_struct_value_address (struct regcache *regcache)
805b725ae77Skettenis {
806b725ae77Skettenis   ULONGEST addr;
807b725ae77Skettenis 
808b725ae77Skettenis   regcache_cooked_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &addr);
809b725ae77Skettenis   return addr;
810e93f7393Sniklas }
811e93f7393Sniklas 
812b725ae77Skettenis static CORE_ADDR
sh_frame_align(struct gdbarch * ignore,CORE_ADDR sp)813b725ae77Skettenis sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
814b725ae77Skettenis {
815b725ae77Skettenis   return sp & ~3;
816b725ae77Skettenis }
817b725ae77Skettenis 
818b725ae77Skettenis /* Function: push_dummy_call (formerly push_arguments)
819b725ae77Skettenis    Setup the function arguments for calling a function in the inferior.
820b725ae77Skettenis 
821b725ae77Skettenis    On the Renesas SH architecture, there are four registers (R4 to R7)
822b725ae77Skettenis    which are dedicated for passing function arguments.  Up to the first
823b725ae77Skettenis    four arguments (depending on size) may go into these registers.
824b725ae77Skettenis    The rest go on the stack.
825b725ae77Skettenis 
826b725ae77Skettenis    MVS: Except on SH variants that have floating point registers.
827b725ae77Skettenis    In that case, float and double arguments are passed in the same
828b725ae77Skettenis    manner, but using FP registers instead of GP registers.
829b725ae77Skettenis 
830b725ae77Skettenis    Arguments that are smaller than 4 bytes will still take up a whole
831b725ae77Skettenis    register or a whole 32-bit word on the stack, and will be
832b725ae77Skettenis    right-justified in the register or the stack word.  This includes
833b725ae77Skettenis    chars, shorts, and small aggregate types.
834b725ae77Skettenis 
835b725ae77Skettenis    Arguments that are larger than 4 bytes may be split between two or
836b725ae77Skettenis    more registers.  If there are not enough registers free, an argument
837b725ae77Skettenis    may be passed partly in a register (or registers), and partly on the
838b725ae77Skettenis    stack.  This includes doubles, long longs, and larger aggregates.
839b725ae77Skettenis    As far as I know, there is no upper limit to the size of aggregates
840b725ae77Skettenis    that will be passed in this way; in other words, the convention of
841b725ae77Skettenis    passing a pointer to a large aggregate instead of a copy is not used.
842b725ae77Skettenis 
843b725ae77Skettenis    MVS: The above appears to be true for the SH variants that do not
844b725ae77Skettenis    have an FPU, however those that have an FPU appear to copy the
845b725ae77Skettenis    aggregate argument onto the stack (and not place it in registers)
846b725ae77Skettenis    if it is larger than 16 bytes (four GP registers).
847b725ae77Skettenis 
848b725ae77Skettenis    An exceptional case exists for struct arguments (and possibly other
849b725ae77Skettenis    aggregates such as arrays) if the size is larger than 4 bytes but
850b725ae77Skettenis    not a multiple of 4 bytes.  In this case the argument is never split
851b725ae77Skettenis    between the registers and the stack, but instead is copied in its
852b725ae77Skettenis    entirety onto the stack, AND also copied into as many registers as
853b725ae77Skettenis    there is room for.  In other words, space in registers permitting,
854b725ae77Skettenis    two copies of the same argument are passed in.  As far as I can tell,
855b725ae77Skettenis    only the one on the stack is used, although that may be a function
856b725ae77Skettenis    of the level of compiler optimization.  I suspect this is a compiler
857b725ae77Skettenis    bug.  Arguments of these odd sizes are left-justified within the
858b725ae77Skettenis    word (as opposed to arguments smaller than 4 bytes, which are
859b725ae77Skettenis    right-justified).
860b725ae77Skettenis 
861b725ae77Skettenis    If the function is to return an aggregate type such as a struct, it
862b725ae77Skettenis    is either returned in the normal return value register R0 (if its
863b725ae77Skettenis    size is no greater than one byte), or else the caller must allocate
864b725ae77Skettenis    space into which the callee will copy the return value (if the size
865b725ae77Skettenis    is greater than one byte).  In this case, a pointer to the return
866b725ae77Skettenis    value location is passed into the callee in register R2, which does
867b725ae77Skettenis    not displace any of the other arguments passed in via registers R4
868b725ae77Skettenis    to R7.   */
869b725ae77Skettenis 
870b725ae77Skettenis /* Helper function to justify value in register according to endianess. */
871b725ae77Skettenis static char *
sh_justify_value_in_reg(struct value * val,int len)872b725ae77Skettenis sh_justify_value_in_reg (struct value *val, int len)
873b725ae77Skettenis {
874b725ae77Skettenis   static char valbuf[4];
875b725ae77Skettenis 
876b725ae77Skettenis   memset (valbuf, 0, sizeof (valbuf));
877b725ae77Skettenis   if (len < 4)
878b725ae77Skettenis     {
879b725ae77Skettenis       /* value gets right-justified in the register or stack word */
880b725ae77Skettenis       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
881b725ae77Skettenis 	memcpy (valbuf + (4 - len), (char *) VALUE_CONTENTS (val), len);
882b725ae77Skettenis       else
883b725ae77Skettenis 	memcpy (valbuf, (char *) VALUE_CONTENTS (val), len);
884b725ae77Skettenis       return valbuf;
885b725ae77Skettenis     }
886b725ae77Skettenis   return (char *) VALUE_CONTENTS (val);
887b725ae77Skettenis }
888b725ae77Skettenis 
889b725ae77Skettenis /* Helper function to eval number of bytes to allocate on stack. */
890b725ae77Skettenis static CORE_ADDR
sh_stack_allocsize(int nargs,struct value ** args)891b725ae77Skettenis sh_stack_allocsize (int nargs, struct value **args)
892b725ae77Skettenis {
893b725ae77Skettenis   int stack_alloc = 0;
894b725ae77Skettenis   while (nargs-- > 0)
895b725ae77Skettenis     stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[nargs])) + 3) & ~3);
896b725ae77Skettenis   return stack_alloc;
897b725ae77Skettenis }
898b725ae77Skettenis 
899b725ae77Skettenis /* Helper functions for getting the float arguments right.  Registers usage
900b725ae77Skettenis    depends on the ABI and the endianess.  The comments should enlighten how
901b725ae77Skettenis    it's intended to work. */
902b725ae77Skettenis 
903b725ae77Skettenis /* This array stores which of the float arg registers are already in use. */
904b725ae77Skettenis static int flt_argreg_array[FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM + 1];
905b725ae77Skettenis 
906b725ae77Skettenis /* This function just resets the above array to "no reg used so far". */
907b725ae77Skettenis static void
sh_init_flt_argreg(void)908b725ae77Skettenis sh_init_flt_argreg (void)
909b725ae77Skettenis {
910b725ae77Skettenis   memset (flt_argreg_array, 0, sizeof flt_argreg_array);
911b725ae77Skettenis }
912b725ae77Skettenis 
913b725ae77Skettenis /* This function returns the next register to use for float arg passing.
914b725ae77Skettenis    It returns either a valid value between FLOAT_ARG0_REGNUM and
915b725ae77Skettenis    FLOAT_ARGLAST_REGNUM if a register is available, otherwise it returns
916b725ae77Skettenis    FLOAT_ARGLAST_REGNUM + 1 to indicate that no register is available.
917b725ae77Skettenis 
918b725ae77Skettenis    Note that register number 0 in flt_argreg_array corresponds with the
919b725ae77Skettenis    real float register fr4.  In contrast to FLOAT_ARG0_REGNUM (value is
920b725ae77Skettenis    29) the parity of the register number is preserved, which is important
921b725ae77Skettenis    for the double register passing test (see the "argreg & 1" test below). */
922b725ae77Skettenis static int
sh_next_flt_argreg(int len)923b725ae77Skettenis sh_next_flt_argreg (int len)
924b725ae77Skettenis {
925b725ae77Skettenis   int argreg;
926b725ae77Skettenis 
927b725ae77Skettenis   /* First search for the next free register. */
928b725ae77Skettenis   for (argreg = 0; argreg <= FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM;
929b725ae77Skettenis        ++argreg)
930b725ae77Skettenis     if (!flt_argreg_array[argreg])
931b725ae77Skettenis       break;
932b725ae77Skettenis 
933b725ae77Skettenis   /* No register left? */
934b725ae77Skettenis   if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM)
935b725ae77Skettenis     return FLOAT_ARGLAST_REGNUM + 1;
936b725ae77Skettenis 
937b725ae77Skettenis   if (len == 8)
938b725ae77Skettenis     {
939b725ae77Skettenis       /* Doubles are always starting in a even register number. */
940b725ae77Skettenis       if (argreg & 1)
941b725ae77Skettenis 	{
942b725ae77Skettenis 	  flt_argreg_array[argreg] = 1;
943b725ae77Skettenis 
944b725ae77Skettenis 	  ++argreg;
945b725ae77Skettenis 
946b725ae77Skettenis 	  /* No register left? */
947b725ae77Skettenis 	  if (argreg > FLOAT_ARGLAST_REGNUM - FLOAT_ARG0_REGNUM)
948b725ae77Skettenis 	    return FLOAT_ARGLAST_REGNUM + 1;
949b725ae77Skettenis 	}
950b725ae77Skettenis       /* Also mark the next register as used. */
951b725ae77Skettenis       flt_argreg_array[argreg + 1] = 1;
952b725ae77Skettenis     }
953b725ae77Skettenis   else if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
954b725ae77Skettenis     {
955b725ae77Skettenis       /* In little endian, gcc passes floats like this: f5, f4, f7, f6, ... */
956b725ae77Skettenis       if (!flt_argreg_array[argreg + 1])
957b725ae77Skettenis 	++argreg;
958b725ae77Skettenis     }
959b725ae77Skettenis   flt_argreg_array[argreg] = 1;
960b725ae77Skettenis   return FLOAT_ARG0_REGNUM + argreg;
961b725ae77Skettenis }
962b725ae77Skettenis 
963b725ae77Skettenis /* Helper function which figures out, if a type is treated like a float type.
964b725ae77Skettenis 
965b725ae77Skettenis    The FPU ABIs have a special way how to treat types as float types.
966b725ae77Skettenis    Structures with exactly one member, which is of type float or double, are
967b725ae77Skettenis    treated exactly as the base types float or double:
968b725ae77Skettenis 
969b725ae77Skettenis      struct sf {
970b725ae77Skettenis        float f;
971b725ae77Skettenis      };
972b725ae77Skettenis 
973b725ae77Skettenis      struct sd {
974b725ae77Skettenis        double d;
975b725ae77Skettenis      };
976b725ae77Skettenis 
977b725ae77Skettenis    are handled the same way as just
978b725ae77Skettenis 
979b725ae77Skettenis      float f;
980b725ae77Skettenis 
981b725ae77Skettenis      double d;
982b725ae77Skettenis 
983b725ae77Skettenis    As a result, arguments of these struct types are pushed into floating point
984b725ae77Skettenis    registers exactly as floats or doubles, using the same decision algorithm.
985b725ae77Skettenis 
986b725ae77Skettenis    The same is valid if these types are used as function return types.  The
987b725ae77Skettenis    above structs are returned in fr0 resp. fr0,fr1 instead of in r0, r0,r1
988b725ae77Skettenis    or even using struct convention as it is for other structs.  */
989b725ae77Skettenis 
990b725ae77Skettenis static int
sh_treat_as_flt_p(struct type * type)991b725ae77Skettenis sh_treat_as_flt_p (struct type *type)
992b725ae77Skettenis {
993b725ae77Skettenis   int len = TYPE_LENGTH (type);
994b725ae77Skettenis 
995b725ae77Skettenis   /* Ordinary float types are obviously treated as float.  */
996b725ae77Skettenis   if (TYPE_CODE (type) == TYPE_CODE_FLT)
997b725ae77Skettenis     return 1;
998b725ae77Skettenis   /* Otherwise non-struct types are not treated as float.  */
999b725ae77Skettenis   if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
1000e93f7393Sniklas     return 0;
1001b725ae77Skettenis   /* Otherwise structs with more than one memeber are not treated as float.  */
1002b725ae77Skettenis   if (TYPE_NFIELDS (type) != 1)
1003b725ae77Skettenis     return 0;
1004b725ae77Skettenis   /* Otherwise if the type of that member is float, the whole type is
1005b725ae77Skettenis      treated as float.  */
1006b725ae77Skettenis   if (TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_FLT)
1007b725ae77Skettenis     return 1;
1008b725ae77Skettenis   /* Otherwise it's not treated as float.  */
1009b725ae77Skettenis   return 0;
1010b725ae77Skettenis }
1011b725ae77Skettenis 
1012b725ae77Skettenis static CORE_ADDR
sh_push_dummy_call_fpu(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)1013b725ae77Skettenis sh_push_dummy_call_fpu (struct gdbarch *gdbarch,
101463addd46Skettenis 			struct value *function,
1015b725ae77Skettenis 			struct regcache *regcache,
1016b725ae77Skettenis 			CORE_ADDR bp_addr, int nargs,
1017b725ae77Skettenis 			struct value **args,
1018b725ae77Skettenis 			CORE_ADDR sp, int struct_return,
1019b725ae77Skettenis 			CORE_ADDR struct_addr)
1020b725ae77Skettenis {
1021b725ae77Skettenis   int stack_offset = 0;
1022b725ae77Skettenis   int argreg = ARG0_REGNUM;
1023b725ae77Skettenis   int flt_argreg = 0;
1024b725ae77Skettenis   int argnum;
1025b725ae77Skettenis   struct type *type;
1026b725ae77Skettenis   CORE_ADDR regval;
1027b725ae77Skettenis   char *val;
1028b725ae77Skettenis   int len, reg_size = 0;
1029b725ae77Skettenis   int pass_on_stack = 0;
1030b725ae77Skettenis   int treat_as_flt;
1031b725ae77Skettenis 
1032b725ae77Skettenis   /* first force sp to a 4-byte alignment */
1033b725ae77Skettenis   sp = sh_frame_align (gdbarch, sp);
1034b725ae77Skettenis 
1035b725ae77Skettenis   if (struct_return)
1036b725ae77Skettenis     regcache_cooked_write_unsigned (regcache,
1037b725ae77Skettenis 				    STRUCT_RETURN_REGNUM, struct_addr);
1038b725ae77Skettenis 
1039b725ae77Skettenis   /* make room on stack for args */
1040b725ae77Skettenis   sp -= sh_stack_allocsize (nargs, args);
1041b725ae77Skettenis 
1042b725ae77Skettenis   /* Initialize float argument mechanism. */
1043b725ae77Skettenis   sh_init_flt_argreg ();
1044b725ae77Skettenis 
1045b725ae77Skettenis   /* Now load as many as possible of the first arguments into
1046b725ae77Skettenis      registers, and push the rest onto the stack.  There are 16 bytes
1047b725ae77Skettenis      in four registers available.  Loop thru args from first to last.  */
1048b725ae77Skettenis   for (argnum = 0; argnum < nargs; argnum++)
1049b725ae77Skettenis     {
1050b725ae77Skettenis       type = VALUE_TYPE (args[argnum]);
1051b725ae77Skettenis       len = TYPE_LENGTH (type);
1052b725ae77Skettenis       val = sh_justify_value_in_reg (args[argnum], len);
1053b725ae77Skettenis 
1054b725ae77Skettenis       /* Some decisions have to be made how various types are handled.
1055b725ae77Skettenis          This also differs in different ABIs. */
1056b725ae77Skettenis       pass_on_stack = 0;
1057b725ae77Skettenis 
1058b725ae77Skettenis       /* Find out the next register to use for a floating point value. */
1059b725ae77Skettenis       treat_as_flt = sh_treat_as_flt_p (type);
1060b725ae77Skettenis       if (treat_as_flt)
1061b725ae77Skettenis 	flt_argreg = sh_next_flt_argreg (len);
1062b725ae77Skettenis       /* In contrast to non-FPU CPUs, arguments are never split between
1063b725ae77Skettenis 	 registers and stack.  If an argument doesn't fit in the remaining
1064b725ae77Skettenis 	 registers it's always pushed entirely on the stack.  */
1065b725ae77Skettenis       else if (len > ((ARGLAST_REGNUM - argreg + 1) * 4))
1066b725ae77Skettenis 	pass_on_stack = 1;
1067b725ae77Skettenis 
1068b725ae77Skettenis       while (len > 0)
1069b725ae77Skettenis 	{
1070b725ae77Skettenis 	  if ((treat_as_flt && flt_argreg > FLOAT_ARGLAST_REGNUM)
1071b725ae77Skettenis 	      || (!treat_as_flt && (argreg > ARGLAST_REGNUM
1072b725ae77Skettenis 	                            || pass_on_stack)))
1073b725ae77Skettenis 	    {
1074b725ae77Skettenis 	      /* The data goes entirely on the stack, 4-byte aligned. */
1075b725ae77Skettenis 	      reg_size = (len + 3) & ~3;
1076b725ae77Skettenis 	      write_memory (sp + stack_offset, val, reg_size);
1077b725ae77Skettenis 	      stack_offset += reg_size;
1078b725ae77Skettenis 	    }
1079b725ae77Skettenis 	  else if (treat_as_flt && flt_argreg <= FLOAT_ARGLAST_REGNUM)
1080b725ae77Skettenis 	    {
1081b725ae77Skettenis 	      /* Argument goes in a float argument register.  */
1082b725ae77Skettenis 	      reg_size = register_size (gdbarch, flt_argreg);
1083b725ae77Skettenis 	      regval = extract_unsigned_integer (val, reg_size);
1084b725ae77Skettenis 	      /* In little endian mode, float types taking two registers
1085b725ae77Skettenis 	         (doubles on sh4, long doubles on sh2e, sh3e and sh4) must
1086b725ae77Skettenis 		 be stored swapped in the argument registers.  The below
1087b725ae77Skettenis 		 code first writes the first 32 bits in the next but one
1088b725ae77Skettenis 		 register, increments the val and len values accordingly
1089b725ae77Skettenis 		 and then proceeds as normal by writing the second 32 bits
1090b725ae77Skettenis 		 into the next register. */
1091b725ae77Skettenis 	      if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE
1092b725ae77Skettenis 	          && TYPE_LENGTH (type) == 2 * reg_size)
1093b725ae77Skettenis 	        {
1094b725ae77Skettenis 		  regcache_cooked_write_unsigned (regcache, flt_argreg + 1,
1095b725ae77Skettenis 						  regval);
1096b725ae77Skettenis 		  val += reg_size;
1097b725ae77Skettenis 		  len -= reg_size;
1098b725ae77Skettenis 		  regval = extract_unsigned_integer (val, reg_size);
1099b725ae77Skettenis 		}
1100b725ae77Skettenis 	      regcache_cooked_write_unsigned (regcache, flt_argreg++, regval);
1101b725ae77Skettenis 	    }
1102b725ae77Skettenis 	  else if (!treat_as_flt && argreg <= ARGLAST_REGNUM)
1103b725ae77Skettenis 	    {
1104b725ae77Skettenis 	      /* there's room in a register */
1105b725ae77Skettenis 	      reg_size = register_size (gdbarch, argreg);
1106b725ae77Skettenis 	      regval = extract_unsigned_integer (val, reg_size);
1107b725ae77Skettenis 	      regcache_cooked_write_unsigned (regcache, argreg++, regval);
1108b725ae77Skettenis 	    }
1109b725ae77Skettenis 	  /* Store the value one register at a time or in one step on stack.  */
1110b725ae77Skettenis 	  len -= reg_size;
1111b725ae77Skettenis 	  val += reg_size;
1112b725ae77Skettenis 	}
1113b725ae77Skettenis     }
1114b725ae77Skettenis 
1115b725ae77Skettenis   /* Store return address. */
1116b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
1117b725ae77Skettenis 
1118b725ae77Skettenis   /* Update stack pointer.  */
1119b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp);
1120b725ae77Skettenis 
1121b725ae77Skettenis   return sp;
1122b725ae77Skettenis }
1123b725ae77Skettenis 
1124b725ae77Skettenis static CORE_ADDR
sh_push_dummy_call_nofpu(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)1125b725ae77Skettenis sh_push_dummy_call_nofpu (struct gdbarch *gdbarch,
112663addd46Skettenis 			  struct value *function,
1127b725ae77Skettenis 			  struct regcache *regcache,
1128b725ae77Skettenis 			  CORE_ADDR bp_addr,
1129b725ae77Skettenis 			  int nargs, struct value **args,
1130b725ae77Skettenis 			  CORE_ADDR sp, int struct_return,
1131b725ae77Skettenis 			  CORE_ADDR struct_addr)
1132b725ae77Skettenis {
1133b725ae77Skettenis   int stack_offset = 0;
1134b725ae77Skettenis   int argreg = ARG0_REGNUM;
1135b725ae77Skettenis   int argnum;
1136b725ae77Skettenis   struct type *type;
1137b725ae77Skettenis   CORE_ADDR regval;
1138b725ae77Skettenis   char *val;
1139b725ae77Skettenis   int len, reg_size;
1140b725ae77Skettenis 
1141b725ae77Skettenis   /* first force sp to a 4-byte alignment */
1142b725ae77Skettenis   sp = sh_frame_align (gdbarch, sp);
1143b725ae77Skettenis 
1144b725ae77Skettenis   if (struct_return)
1145b725ae77Skettenis     regcache_cooked_write_unsigned (regcache,
1146b725ae77Skettenis 				    STRUCT_RETURN_REGNUM, struct_addr);
1147b725ae77Skettenis 
1148b725ae77Skettenis   /* make room on stack for args */
1149b725ae77Skettenis   sp -= sh_stack_allocsize (nargs, args);
1150b725ae77Skettenis 
1151b725ae77Skettenis   /* Now load as many as possible of the first arguments into
1152b725ae77Skettenis      registers, and push the rest onto the stack.  There are 16 bytes
1153b725ae77Skettenis      in four registers available.  Loop thru args from first to last.  */
1154b725ae77Skettenis   for (argnum = 0; argnum < nargs; argnum++)
1155b725ae77Skettenis     {
1156b725ae77Skettenis       type = VALUE_TYPE (args[argnum]);
1157b725ae77Skettenis       len = TYPE_LENGTH (type);
1158b725ae77Skettenis       val = sh_justify_value_in_reg (args[argnum], len);
1159b725ae77Skettenis 
1160b725ae77Skettenis       while (len > 0)
1161b725ae77Skettenis 	{
1162b725ae77Skettenis 	  if (argreg > ARGLAST_REGNUM)
1163b725ae77Skettenis 	    {
1164b725ae77Skettenis 	      /* The remainder of the data goes entirely on the stack,
1165b725ae77Skettenis 	         4-byte aligned. */
1166b725ae77Skettenis 	      reg_size = (len + 3) & ~3;
1167b725ae77Skettenis 	      write_memory (sp + stack_offset, val, reg_size);
1168b725ae77Skettenis 	      stack_offset += reg_size;
1169b725ae77Skettenis 	    }
1170b725ae77Skettenis 	  else if (argreg <= ARGLAST_REGNUM)
1171b725ae77Skettenis 	    {
1172b725ae77Skettenis 	      /* there's room in a register */
1173b725ae77Skettenis 	      reg_size = register_size (gdbarch, argreg);
1174b725ae77Skettenis 	      regval = extract_unsigned_integer (val, reg_size);
1175b725ae77Skettenis 	      regcache_cooked_write_unsigned (regcache, argreg++, regval);
1176b725ae77Skettenis 	    }
1177b725ae77Skettenis 	  /* Store the value reg_size bytes at a time.  This means that things
1178b725ae77Skettenis 	     larger than reg_size bytes may go partly in registers and partly
1179b725ae77Skettenis 	     on the stack.  */
1180b725ae77Skettenis 	  len -= reg_size;
1181b725ae77Skettenis 	  val += reg_size;
1182b725ae77Skettenis 	}
1183b725ae77Skettenis     }
1184b725ae77Skettenis 
1185b725ae77Skettenis   /* Store return address. */
1186b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, PR_REGNUM, bp_addr);
1187b725ae77Skettenis 
1188b725ae77Skettenis   /* Update stack pointer.  */
1189b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, SP_REGNUM, sp);
1190b725ae77Skettenis 
1191b725ae77Skettenis   return sp;
1192b725ae77Skettenis }
1193b725ae77Skettenis 
1194b725ae77Skettenis /* Find a function's return value in the appropriate registers (in
1195b725ae77Skettenis    regbuf), and copy it into valbuf.  Extract from an array REGBUF
1196b725ae77Skettenis    containing the (raw) register state a function return value of type
1197b725ae77Skettenis    TYPE, and copy that, in virtual format, into VALBUF.  */
1198b725ae77Skettenis static void
sh_default_extract_return_value(struct type * type,struct regcache * regcache,void * valbuf)1199b725ae77Skettenis sh_default_extract_return_value (struct type *type, struct regcache *regcache,
1200b725ae77Skettenis 				 void *valbuf)
1201b725ae77Skettenis {
1202b725ae77Skettenis   int len = TYPE_LENGTH (type);
1203b725ae77Skettenis   int return_register = R0_REGNUM;
1204b725ae77Skettenis   int offset;
1205b725ae77Skettenis 
1206b725ae77Skettenis   if (len <= 4)
1207b725ae77Skettenis     {
1208b725ae77Skettenis       ULONGEST c;
1209b725ae77Skettenis 
1210b725ae77Skettenis       regcache_cooked_read_unsigned (regcache, R0_REGNUM, &c);
1211b725ae77Skettenis       store_unsigned_integer (valbuf, len, c);
1212b725ae77Skettenis     }
1213b725ae77Skettenis   else if (len == 8)
1214b725ae77Skettenis     {
1215b725ae77Skettenis       int i, regnum = R0_REGNUM;
1216b725ae77Skettenis       for (i = 0; i < len; i += 4)
1217b725ae77Skettenis 	regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
1218b725ae77Skettenis     }
1219b725ae77Skettenis   else
1220b725ae77Skettenis     error ("bad size for return value");
1221b725ae77Skettenis }
1222b725ae77Skettenis 
1223b725ae77Skettenis static void
sh3e_sh4_extract_return_value(struct type * type,struct regcache * regcache,void * valbuf)1224b725ae77Skettenis sh3e_sh4_extract_return_value (struct type *type, struct regcache *regcache,
1225b725ae77Skettenis 			       void *valbuf)
1226b725ae77Skettenis {
1227b725ae77Skettenis   if (sh_treat_as_flt_p (type))
1228b725ae77Skettenis     {
1229b725ae77Skettenis       int len = TYPE_LENGTH (type);
1230b725ae77Skettenis       int i, regnum = FP0_REGNUM;
1231b725ae77Skettenis       for (i = 0; i < len; i += 4)
1232b725ae77Skettenis 	if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
1233b725ae77Skettenis 	  regcache_raw_read (regcache, regnum++, (char *) valbuf + len - 4 - i);
1234b725ae77Skettenis 	else
1235b725ae77Skettenis 	  regcache_raw_read (regcache, regnum++, (char *) valbuf + i);
1236b725ae77Skettenis     }
1237b725ae77Skettenis   else
1238b725ae77Skettenis     sh_default_extract_return_value (type, regcache, valbuf);
1239b725ae77Skettenis }
1240b725ae77Skettenis 
1241b725ae77Skettenis /* Write into appropriate registers a function return value
1242b725ae77Skettenis    of type TYPE, given in virtual format.
1243b725ae77Skettenis    If the architecture is sh4 or sh3e, store a function's return value
1244b725ae77Skettenis    in the R0 general register or in the FP0 floating point register,
1245b725ae77Skettenis    depending on the type of the return value. In all the other cases
1246b725ae77Skettenis    the result is stored in r0, left-justified. */
1247b725ae77Skettenis static void
sh_default_store_return_value(struct type * type,struct regcache * regcache,const void * valbuf)1248b725ae77Skettenis sh_default_store_return_value (struct type *type, struct regcache *regcache,
1249b725ae77Skettenis 			       const void *valbuf)
1250b725ae77Skettenis {
1251b725ae77Skettenis   ULONGEST val;
1252b725ae77Skettenis   int len = TYPE_LENGTH (type);
1253b725ae77Skettenis 
1254b725ae77Skettenis   if (len <= 4)
1255b725ae77Skettenis     {
1256b725ae77Skettenis       val = extract_unsigned_integer (valbuf, len);
1257b725ae77Skettenis       regcache_cooked_write_unsigned (regcache, R0_REGNUM, val);
1258b725ae77Skettenis     }
1259b725ae77Skettenis   else
1260b725ae77Skettenis     {
1261b725ae77Skettenis       int i, regnum = R0_REGNUM;
1262b725ae77Skettenis       for (i = 0; i < len; i += 4)
1263b725ae77Skettenis 	regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
1264b725ae77Skettenis     }
1265b725ae77Skettenis }
1266b725ae77Skettenis 
1267b725ae77Skettenis static void
sh3e_sh4_store_return_value(struct type * type,struct regcache * regcache,const void * valbuf)1268b725ae77Skettenis sh3e_sh4_store_return_value (struct type *type, struct regcache *regcache,
1269b725ae77Skettenis 			     const void *valbuf)
1270b725ae77Skettenis {
1271b725ae77Skettenis   if (sh_treat_as_flt_p (type))
1272b725ae77Skettenis     {
1273b725ae77Skettenis       int len = TYPE_LENGTH (type);
1274b725ae77Skettenis       int i, regnum = FP0_REGNUM;
1275b725ae77Skettenis       for (i = 0; i < len; i += 4)
127663addd46Skettenis 	if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
127763addd46Skettenis 	  regcache_raw_write (regcache, regnum++,
127863addd46Skettenis 			      (char *) valbuf + len - 4 - i);
127963addd46Skettenis 	else
1280b725ae77Skettenis 	  regcache_raw_write (regcache, regnum++, (char *) valbuf + i);
1281b725ae77Skettenis     }
1282b725ae77Skettenis   else
1283b725ae77Skettenis     sh_default_store_return_value (type, regcache, valbuf);
1284e93f7393Sniklas }
1285e93f7393Sniklas 
128663addd46Skettenis static enum return_value_convention
sh_return_value_nofpu(struct gdbarch * gdbarch,struct type * type,struct regcache * regcache,void * readbuf,const void * writebuf)128763addd46Skettenis sh_return_value_nofpu (struct gdbarch *gdbarch, struct type *type,
128863addd46Skettenis 		       struct regcache *regcache,
128963addd46Skettenis 		       void *readbuf, const void *writebuf)
129063addd46Skettenis {
129163addd46Skettenis   if (sh_use_struct_convention (0, type))
129263addd46Skettenis     return RETURN_VALUE_STRUCT_CONVENTION;
129363addd46Skettenis   if (writebuf)
129463addd46Skettenis     sh_default_store_return_value (type, regcache, writebuf);
129563addd46Skettenis   else if (readbuf)
129663addd46Skettenis     sh_default_extract_return_value (type, regcache, readbuf);
129763addd46Skettenis   return RETURN_VALUE_REGISTER_CONVENTION;
129863addd46Skettenis }
129963addd46Skettenis 
130063addd46Skettenis static enum return_value_convention
sh_return_value_fpu(struct gdbarch * gdbarch,struct type * type,struct regcache * regcache,void * readbuf,const void * writebuf)130163addd46Skettenis sh_return_value_fpu (struct gdbarch *gdbarch, struct type *type,
130263addd46Skettenis 		     struct regcache *regcache,
130363addd46Skettenis 		     void *readbuf, const void *writebuf)
130463addd46Skettenis {
130563addd46Skettenis   if (sh_use_struct_convention (0, type))
130663addd46Skettenis     return RETURN_VALUE_STRUCT_CONVENTION;
130763addd46Skettenis   if (writebuf)
130863addd46Skettenis     sh3e_sh4_store_return_value (type, regcache, writebuf);
130963addd46Skettenis   else if (readbuf)
131063addd46Skettenis     sh3e_sh4_extract_return_value (type, regcache, readbuf);
131163addd46Skettenis   return RETURN_VALUE_REGISTER_CONVENTION;
131263addd46Skettenis }
131363addd46Skettenis 
1314e93f7393Sniklas /* Print the registers in a form similar to the E7000 */
1315e93f7393Sniklas 
1316e93f7393Sniklas static void
sh_generic_show_regs(void)1317b725ae77Skettenis sh_generic_show_regs (void)
1318e93f7393Sniklas {
1319b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1320b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1321b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1322b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1323b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1324b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1325e93f7393Sniklas 
1326b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1327b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1328b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1329b725ae77Skettenis 
1330b725ae77Skettenis   printf_filtered
1331b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1332b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1333b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1334b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1335b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1336b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1337b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1338b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1339b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1340b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1341e93f7393Sniklas }
1342b725ae77Skettenis 
1343b725ae77Skettenis static void
sh3_show_regs(void)1344b725ae77Skettenis sh3_show_regs (void)
1345b725ae77Skettenis {
1346b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1347b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1348b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1349b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1350b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1351b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1352b725ae77Skettenis 
1353b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1354b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1355b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1356b725ae77Skettenis   printf_filtered (" SSR=%08lx SPC=%08lx",
1357b725ae77Skettenis 		   (long) read_register (SSR_REGNUM),
1358b725ae77Skettenis 		   (long) read_register (SPC_REGNUM));
1359b725ae77Skettenis 
1360b725ae77Skettenis   printf_filtered
1361b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1362b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1363b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1364b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1365b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1366b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1367b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1368b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1369b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1370b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1371b725ae77Skettenis }
1372b725ae77Skettenis 
1373b725ae77Skettenis 
1374b725ae77Skettenis static void
sh2e_show_regs(void)1375b725ae77Skettenis sh2e_show_regs (void)
1376b725ae77Skettenis {
1377b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1378b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1379b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1380b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1381b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1382b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1383b725ae77Skettenis 
1384b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1385b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1386b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1387b725ae77Skettenis   printf_filtered (" FPUL=%08lx FPSCR=%08lx",
1388b725ae77Skettenis 		   (long) read_register (FPUL_REGNUM),
1389b725ae77Skettenis 		   (long) read_register (FPSCR_REGNUM));
1390b725ae77Skettenis 
1391b725ae77Skettenis   printf_filtered
1392b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1393b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1394b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1395b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1396b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1397b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1398b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1399b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1400b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1401b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1402b725ae77Skettenis 
1403b725ae77Skettenis   printf_filtered (("FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7));
1404b725ae77Skettenis   printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15));
1405b725ae77Skettenis }
1406b725ae77Skettenis 
1407*2f050487Smiod #ifdef notyet
1408b725ae77Skettenis static void
sh2a_show_regs(void)140963addd46Skettenis sh2a_show_regs (void)
141063addd46Skettenis {
141163addd46Skettenis   int pr = read_register (FPSCR_REGNUM) & 0x80000;
141263addd46Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
141363addd46Skettenis 		   paddr (read_register (PC_REGNUM)),
141463addd46Skettenis 		   (long) read_register (SR_REGNUM),
141563addd46Skettenis 		   (long) read_register (PR_REGNUM),
141663addd46Skettenis 		   (long) read_register (MACH_REGNUM),
141763addd46Skettenis 		   (long) read_register (MACL_REGNUM));
141863addd46Skettenis 
141963addd46Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx TBR=%08lx",
142063addd46Skettenis 		   (long) read_register (GBR_REGNUM),
142163addd46Skettenis 		   (long) read_register (VBR_REGNUM),
142263addd46Skettenis 		   (long) read_register (TBR_REGNUM));
142363addd46Skettenis   printf_filtered (" FPUL=%08lx FPSCR=%08lx\n",
142463addd46Skettenis 		   (long) read_register (FPUL_REGNUM),
142563addd46Skettenis 		   (long) read_register (FPSCR_REGNUM));
142663addd46Skettenis 
142763addd46Skettenis   printf_filtered ("R0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
142863addd46Skettenis 		   (long) read_register (0), (long) read_register (1),
142963addd46Skettenis 		   (long) read_register (2), (long) read_register (3),
143063addd46Skettenis 		   (long) read_register (4), (long) read_register (5),
143163addd46Skettenis 		   (long) read_register (6), (long) read_register (7));
143263addd46Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
143363addd46Skettenis 		   (long) read_register (8), (long) read_register (9),
143463addd46Skettenis 		   (long) read_register (10), (long) read_register (11),
143563addd46Skettenis 		   (long) read_register (12), (long) read_register (13),
143663addd46Skettenis 		   (long) read_register (14), (long) read_register (15));
143763addd46Skettenis 
143863addd46Skettenis   printf_filtered ((pr
143963addd46Skettenis 		    ? "DR0-DR6  %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n"
144063addd46Skettenis 		    :
144163addd46Skettenis 		    "FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
144263addd46Skettenis 		   (long) read_register (FP0_REGNUM + 0),
144363addd46Skettenis 		   (long) read_register (FP0_REGNUM + 1),
144463addd46Skettenis 		   (long) read_register (FP0_REGNUM + 2),
144563addd46Skettenis 		   (long) read_register (FP0_REGNUM + 3),
144663addd46Skettenis 		   (long) read_register (FP0_REGNUM + 4),
144763addd46Skettenis 		   (long) read_register (FP0_REGNUM + 5),
144863addd46Skettenis 		   (long) read_register (FP0_REGNUM + 6),
144963addd46Skettenis 		   (long) read_register (FP0_REGNUM + 7));
145063addd46Skettenis   printf_filtered ((pr ?
145163addd46Skettenis 		    "DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" :
145263addd46Skettenis 		    "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
145363addd46Skettenis 		   (long) read_register (FP0_REGNUM + 8),
145463addd46Skettenis 		   (long) read_register (FP0_REGNUM + 9),
145563addd46Skettenis 		   (long) read_register (FP0_REGNUM + 10),
145663addd46Skettenis 		   (long) read_register (FP0_REGNUM + 11),
145763addd46Skettenis 		   (long) read_register (FP0_REGNUM + 12),
145863addd46Skettenis 		   (long) read_register (FP0_REGNUM + 13),
145963addd46Skettenis 		   (long) read_register (FP0_REGNUM + 14),
146063addd46Skettenis 		   (long) read_register (FP0_REGNUM + 15));
146163addd46Skettenis   printf_filtered ("BANK=%-3d\n", (int) read_register (BANK_REGNUM));
146263addd46Skettenis   printf_filtered ("R0b - R7b  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
146363addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 0),
146463addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 1),
146563addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 2),
146663addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 3),
146763addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 4),
146863addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 5),
146963addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 6),
147063addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 7));
147163addd46Skettenis   printf_filtered ("R8b - R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
147263addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 8),
147363addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 9),
147463addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 10),
147563addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 11),
147663addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 12),
147763addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 13),
147863addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 14));
147963addd46Skettenis   printf_filtered ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n",
148063addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 15),
148163addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 16),
148263addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 17),
148363addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 18),
148463addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 19));
148563addd46Skettenis }
148663addd46Skettenis 
148763addd46Skettenis static void
sh2a_nofpu_show_regs(void)148863addd46Skettenis sh2a_nofpu_show_regs (void)
148963addd46Skettenis {
149063addd46Skettenis   int pr = read_register (FPSCR_REGNUM) & 0x80000;
149163addd46Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
149263addd46Skettenis 		   paddr (read_register (PC_REGNUM)),
149363addd46Skettenis 		   (long) read_register (SR_REGNUM),
149463addd46Skettenis 		   (long) read_register (PR_REGNUM),
149563addd46Skettenis 		   (long) read_register (MACH_REGNUM),
149663addd46Skettenis 		   (long) read_register (MACL_REGNUM));
149763addd46Skettenis 
149863addd46Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx TBR=%08lx",
149963addd46Skettenis 		   (long) read_register (GBR_REGNUM),
150063addd46Skettenis 		   (long) read_register (VBR_REGNUM),
150163addd46Skettenis 		   (long) read_register (TBR_REGNUM));
150263addd46Skettenis   printf_filtered (" FPUL=%08lx FPSCR=%08lx\n",
150363addd46Skettenis 		   (long) read_register (FPUL_REGNUM),
150463addd46Skettenis 		   (long) read_register (FPSCR_REGNUM));
150563addd46Skettenis 
150663addd46Skettenis   printf_filtered ("R0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
150763addd46Skettenis 		   (long) read_register (0), (long) read_register (1),
150863addd46Skettenis 		   (long) read_register (2), (long) read_register (3),
150963addd46Skettenis 		   (long) read_register (4), (long) read_register (5),
151063addd46Skettenis 		   (long) read_register (6), (long) read_register (7));
151163addd46Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
151263addd46Skettenis 		   (long) read_register (8), (long) read_register (9),
151363addd46Skettenis 		   (long) read_register (10), (long) read_register (11),
151463addd46Skettenis 		   (long) read_register (12), (long) read_register (13),
151563addd46Skettenis 		   (long) read_register (14), (long) read_register (15));
151663addd46Skettenis 
151763addd46Skettenis   printf_filtered ("BANK=%-3d\n", (int) read_register (BANK_REGNUM));
151863addd46Skettenis   printf_filtered ("R0b - R7b  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
151963addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 0),
152063addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 1),
152163addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 2),
152263addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 3),
152363addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 4),
152463addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 5),
152563addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 6),
152663addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 7));
152763addd46Skettenis   printf_filtered ("R8b - R14b %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
152863addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 8),
152963addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 9),
153063addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 10),
153163addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 11),
153263addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 12),
153363addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 13),
153463addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 14));
153563addd46Skettenis   printf_filtered ("MACHb=%08lx IVNb=%08lx PRb=%08lx GBRb=%08lx MACLb=%08lx\n",
153663addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 15),
153763addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 16),
153863addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 17),
153963addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 18),
154063addd46Skettenis 		   (long) read_register (R0_BANK0_REGNUM + 19));
154163addd46Skettenis }
1542*2f050487Smiod #endif
154363addd46Skettenis 
154463addd46Skettenis static void
sh3e_show_regs(void)1545b725ae77Skettenis sh3e_show_regs (void)
1546b725ae77Skettenis {
1547b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1548b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1549b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1550b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1551b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1552b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1553b725ae77Skettenis 
1554b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1555b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1556b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1557b725ae77Skettenis   printf_filtered (" SSR=%08lx SPC=%08lx",
1558b725ae77Skettenis 		   (long) read_register (SSR_REGNUM),
1559b725ae77Skettenis 		   (long) read_register (SPC_REGNUM));
1560b725ae77Skettenis   printf_filtered (" FPUL=%08lx FPSCR=%08lx",
1561b725ae77Skettenis 		   (long) read_register (FPUL_REGNUM),
1562b725ae77Skettenis 		   (long) read_register (FPSCR_REGNUM));
1563b725ae77Skettenis 
1564b725ae77Skettenis   printf_filtered
1565b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1566b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1567b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1568b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1569b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1570b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1571b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1572b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1573b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1574b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1575b725ae77Skettenis 
1576b725ae77Skettenis   printf_filtered (("FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 0), (long) read_register (FP0_REGNUM + 1), (long) read_register (FP0_REGNUM + 2), (long) read_register (FP0_REGNUM + 3), (long) read_register (FP0_REGNUM + 4), (long) read_register (FP0_REGNUM + 5), (long) read_register (FP0_REGNUM + 6), (long) read_register (FP0_REGNUM + 7));
1577b725ae77Skettenis   printf_filtered (("FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"), (long) read_register (FP0_REGNUM + 8), (long) read_register (FP0_REGNUM + 9), (long) read_register (FP0_REGNUM + 10), (long) read_register (FP0_REGNUM + 11), (long) read_register (FP0_REGNUM + 12), (long) read_register (FP0_REGNUM + 13), (long) read_register (FP0_REGNUM + 14), (long) read_register (FP0_REGNUM + 15));
1578b725ae77Skettenis }
1579b725ae77Skettenis 
1580b725ae77Skettenis static void
sh3_dsp_show_regs(void)1581b725ae77Skettenis sh3_dsp_show_regs (void)
1582b725ae77Skettenis {
1583b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1584b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1585b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1586b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1587b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1588b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1589b725ae77Skettenis 
1590b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1591b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1592b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1593b725ae77Skettenis 
1594b725ae77Skettenis   printf_filtered (" SSR=%08lx SPC=%08lx",
1595b725ae77Skettenis 		   (long) read_register (SSR_REGNUM),
1596b725ae77Skettenis 		   (long) read_register (SPC_REGNUM));
1597b725ae77Skettenis 
1598b725ae77Skettenis   printf_filtered (" DSR=%08lx", (long) read_register (DSR_REGNUM));
1599b725ae77Skettenis 
1600b725ae77Skettenis   printf_filtered
1601b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1602b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1603b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1604b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1605b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1606b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1607b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1608b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1609b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1610b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1611b725ae77Skettenis 
1612b725ae77Skettenis   printf_filtered
1613b725ae77Skettenis     ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
1614b725ae77Skettenis      (long) read_register (A0G_REGNUM) & 0xff,
1615b725ae77Skettenis      (long) read_register (A0_REGNUM), (long) read_register (M0_REGNUM),
1616b725ae77Skettenis      (long) read_register (X0_REGNUM), (long) read_register (Y0_REGNUM),
1617b725ae77Skettenis      (long) read_register (RS_REGNUM), (long) read_register (MOD_REGNUM));
1618b725ae77Skettenis   printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
1619b725ae77Skettenis 		   (long) read_register (A1G_REGNUM) & 0xff,
1620b725ae77Skettenis 		   (long) read_register (A1_REGNUM),
1621b725ae77Skettenis 		   (long) read_register (M1_REGNUM),
1622b725ae77Skettenis 		   (long) read_register (X1_REGNUM),
1623b725ae77Skettenis 		   (long) read_register (Y1_REGNUM),
1624b725ae77Skettenis 		   (long) read_register (RE_REGNUM));
1625b725ae77Skettenis }
1626b725ae77Skettenis 
1627b725ae77Skettenis static void
sh4_show_regs(void)1628b725ae77Skettenis sh4_show_regs (void)
1629b725ae77Skettenis {
1630b725ae77Skettenis   int pr = read_register (FPSCR_REGNUM) & 0x80000;
1631b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1632b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1633b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1634b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1635b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1636b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1637b725ae77Skettenis 
1638b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1639b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1640b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1641b725ae77Skettenis   printf_filtered (" SSR=%08lx SPC=%08lx",
1642b725ae77Skettenis 		   (long) read_register (SSR_REGNUM),
1643b725ae77Skettenis 		   (long) read_register (SPC_REGNUM));
1644b725ae77Skettenis   printf_filtered (" FPUL=%08lx FPSCR=%08lx",
1645b725ae77Skettenis 		   (long) read_register (FPUL_REGNUM),
1646b725ae77Skettenis 		   (long) read_register (FPSCR_REGNUM));
1647b725ae77Skettenis 
1648b725ae77Skettenis   printf_filtered
1649b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1650b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1651b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1652b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1653b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1654b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1655b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1656b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1657b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1658b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1659b725ae77Skettenis 
1660b725ae77Skettenis   printf_filtered ((pr
1661b725ae77Skettenis 		    ? "DR0-DR6  %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n"
1662b725ae77Skettenis 		    :
1663b725ae77Skettenis 		    "FP0-FP7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
1664b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 0),
1665b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 1),
1666b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 2),
1667b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 3),
1668b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 4),
1669b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 5),
1670b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 6),
1671b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 7));
1672b725ae77Skettenis   printf_filtered ((pr ?
1673b725ae77Skettenis 		    "DR8-DR14 %08lx%08lx %08lx%08lx %08lx%08lx %08lx%08lx\n" :
1674b725ae77Skettenis 		    "FP8-FP15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n"),
1675b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 8),
1676b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 9),
1677b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 10),
1678b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 11),
1679b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 12),
1680b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 13),
1681b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 14),
1682b725ae77Skettenis 		   (long) read_register (FP0_REGNUM + 15));
1683b725ae77Skettenis }
1684b725ae77Skettenis 
1685b725ae77Skettenis static void
sh4_nofpu_show_regs(void)1686b725ae77Skettenis sh4_nofpu_show_regs (void)
1687b725ae77Skettenis {
1688b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1689b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1690b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1691b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1692b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1693b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1694b725ae77Skettenis 
1695b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1696b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1697b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1698b725ae77Skettenis   printf_filtered (" SSR=%08lx SPC=%08lx",
1699b725ae77Skettenis 		   (long) read_register (SSR_REGNUM),
1700b725ae77Skettenis 		   (long) read_register (SPC_REGNUM));
1701b725ae77Skettenis 
1702b725ae77Skettenis   printf_filtered
1703b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1704b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1705b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1706b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1707b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1708b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1709b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1710b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1711b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1712b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1713b725ae77Skettenis }
1714b725ae77Skettenis 
1715b725ae77Skettenis static void
sh_dsp_show_regs(void)1716b725ae77Skettenis sh_dsp_show_regs (void)
1717b725ae77Skettenis {
1718b725ae77Skettenis   printf_filtered ("PC=%s SR=%08lx PR=%08lx MACH=%08lx MACHL=%08lx\n",
1719b725ae77Skettenis 		   paddr (read_register (PC_REGNUM)),
1720b725ae77Skettenis 		   (long) read_register (SR_REGNUM),
1721b725ae77Skettenis 		   (long) read_register (PR_REGNUM),
1722b725ae77Skettenis 		   (long) read_register (MACH_REGNUM),
1723b725ae77Skettenis 		   (long) read_register (MACL_REGNUM));
1724b725ae77Skettenis 
1725b725ae77Skettenis   printf_filtered ("GBR=%08lx VBR=%08lx",
1726b725ae77Skettenis 		   (long) read_register (GBR_REGNUM),
1727b725ae77Skettenis 		   (long) read_register (VBR_REGNUM));
1728b725ae77Skettenis 
1729b725ae77Skettenis   printf_filtered (" DSR=%08lx", (long) read_register (DSR_REGNUM));
1730b725ae77Skettenis 
1731b725ae77Skettenis   printf_filtered
1732b725ae77Skettenis     ("\nR0-R7  %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1733b725ae77Skettenis      (long) read_register (0), (long) read_register (1),
1734b725ae77Skettenis      (long) read_register (2), (long) read_register (3),
1735b725ae77Skettenis      (long) read_register (4), (long) read_register (5),
1736b725ae77Skettenis      (long) read_register (6), (long) read_register (7));
1737b725ae77Skettenis   printf_filtered ("R8-R15 %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1738b725ae77Skettenis 		   (long) read_register (8), (long) read_register (9),
1739b725ae77Skettenis 		   (long) read_register (10), (long) read_register (11),
1740b725ae77Skettenis 		   (long) read_register (12), (long) read_register (13),
1741b725ae77Skettenis 		   (long) read_register (14), (long) read_register (15));
1742b725ae77Skettenis 
1743b725ae77Skettenis   printf_filtered
1744b725ae77Skettenis     ("A0G=%02lx A0=%08lx M0=%08lx X0=%08lx Y0=%08lx RS=%08lx MOD=%08lx\n",
1745b725ae77Skettenis      (long) read_register (A0G_REGNUM) & 0xff,
1746b725ae77Skettenis      (long) read_register (A0_REGNUM), (long) read_register (M0_REGNUM),
1747b725ae77Skettenis      (long) read_register (X0_REGNUM), (long) read_register (Y0_REGNUM),
1748b725ae77Skettenis      (long) read_register (RS_REGNUM), (long) read_register (MOD_REGNUM));
1749b725ae77Skettenis   printf_filtered ("A1G=%02lx A1=%08lx M1=%08lx X1=%08lx Y1=%08lx RE=%08lx\n",
1750b725ae77Skettenis 		   (long) read_register (A1G_REGNUM) & 0xff,
1751b725ae77Skettenis 		   (long) read_register (A1_REGNUM),
1752b725ae77Skettenis 		   (long) read_register (M1_REGNUM),
1753b725ae77Skettenis 		   (long) read_register (X1_REGNUM),
1754b725ae77Skettenis 		   (long) read_register (Y1_REGNUM),
1755b725ae77Skettenis 		   (long) read_register (RE_REGNUM));
1756b725ae77Skettenis }
1757b725ae77Skettenis 
1758b725ae77Skettenis static void
sh_show_regs_command(char * args,int from_tty)1759b725ae77Skettenis sh_show_regs_command (char *args, int from_tty)
1760b725ae77Skettenis {
1761b725ae77Skettenis   if (sh_show_regs)
1762b725ae77Skettenis     (*sh_show_regs) ();
1763b725ae77Skettenis }
1764b725ae77Skettenis 
1765*2f050487Smiod #ifdef notyet
176663addd46Skettenis static struct type *
sh_sh2a_register_type(struct gdbarch * gdbarch,int reg_nr)176763addd46Skettenis sh_sh2a_register_type (struct gdbarch *gdbarch, int reg_nr)
176863addd46Skettenis {
176963addd46Skettenis   if ((reg_nr >= FP0_REGNUM
177063addd46Skettenis        && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
177163addd46Skettenis     return builtin_type_float;
177263addd46Skettenis   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
177363addd46Skettenis     return builtin_type_double;
177463addd46Skettenis   else
177563addd46Skettenis     return builtin_type_int;
177663addd46Skettenis }
1777*2f050487Smiod #endif
177863addd46Skettenis 
1779b725ae77Skettenis /* Return the GDB type object for the "standard" data type
1780b725ae77Skettenis    of data in register N.  */
1781b725ae77Skettenis static struct type *
sh_sh3e_register_type(struct gdbarch * gdbarch,int reg_nr)1782b725ae77Skettenis sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr)
1783b725ae77Skettenis {
1784b725ae77Skettenis   if ((reg_nr >= FP0_REGNUM
1785b725ae77Skettenis        && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
1786b725ae77Skettenis     return builtin_type_float;
1787b725ae77Skettenis   else
1788b725ae77Skettenis     return builtin_type_int;
1789b725ae77Skettenis }
1790b725ae77Skettenis 
1791b725ae77Skettenis static struct type *
sh_sh4_build_float_register_type(int high)1792b725ae77Skettenis sh_sh4_build_float_register_type (int high)
1793b725ae77Skettenis {
1794b725ae77Skettenis   struct type *temp;
1795b725ae77Skettenis 
1796b725ae77Skettenis   temp = create_range_type (NULL, builtin_type_int, 0, high);
1797b725ae77Skettenis   return create_array_type (NULL, builtin_type_float, temp);
1798b725ae77Skettenis }
1799b725ae77Skettenis 
1800b725ae77Skettenis static struct type *
sh_sh4_register_type(struct gdbarch * gdbarch,int reg_nr)1801b725ae77Skettenis sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr)
1802b725ae77Skettenis {
1803b725ae77Skettenis   if ((reg_nr >= FP0_REGNUM
1804b725ae77Skettenis        && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM))
1805b725ae77Skettenis     return builtin_type_float;
1806b725ae77Skettenis   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
1807b725ae77Skettenis     return builtin_type_double;
1808b725ae77Skettenis   else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
1809b725ae77Skettenis     return sh_sh4_build_float_register_type (3);
1810b725ae77Skettenis   else
1811b725ae77Skettenis     return builtin_type_int;
1812b725ae77Skettenis }
1813b725ae77Skettenis 
1814b725ae77Skettenis static struct type *
sh_default_register_type(struct gdbarch * gdbarch,int reg_nr)1815b725ae77Skettenis sh_default_register_type (struct gdbarch *gdbarch, int reg_nr)
1816b725ae77Skettenis {
1817b725ae77Skettenis   return builtin_type_int;
1818b725ae77Skettenis }
1819b725ae77Skettenis 
1820b725ae77Skettenis /* On the sh4, the DRi pseudo registers are problematic if the target
1821b725ae77Skettenis    is little endian. When the user writes one of those registers, for
1822b725ae77Skettenis    instance with 'ser var $dr0=1', we want the double to be stored
1823b725ae77Skettenis    like this:
1824b725ae77Skettenis    fr0 = 0x00 0x00 0x00 0x00 0x00 0xf0 0x3f
1825b725ae77Skettenis    fr1 = 0x00 0x00 0x00 0x00 0x00 0x00 0x00
1826b725ae77Skettenis 
1827b725ae77Skettenis    This corresponds to little endian byte order & big endian word
1828b725ae77Skettenis    order.  However if we let gdb write the register w/o conversion, it
1829b725ae77Skettenis    will write fr0 and fr1 this way:
1830b725ae77Skettenis    fr0 = 0x00 0x00 0x00 0x00 0x00 0x00 0x00
1831b725ae77Skettenis    fr1 = 0x00 0x00 0x00 0x00 0x00 0xf0 0x3f
1832b725ae77Skettenis    because it will consider fr0 and fr1 as a single LE stretch of memory.
1833b725ae77Skettenis 
1834b725ae77Skettenis    To achieve what we want we must force gdb to store things in
1835b725ae77Skettenis    floatformat_ieee_double_littlebyte_bigword (which is defined in
1836b725ae77Skettenis    include/floatformat.h and libiberty/floatformat.c.
1837b725ae77Skettenis 
1838b725ae77Skettenis    In case the target is big endian, there is no problem, the
1839b725ae77Skettenis    raw bytes will look like:
1840b725ae77Skettenis    fr0 = 0x3f 0xf0 0x00 0x00 0x00 0x00 0x00
1841b725ae77Skettenis    fr1 = 0x00 0x00 0x00 0x00 0x00 0x00 0x00
1842b725ae77Skettenis 
1843b725ae77Skettenis    The other pseudo registers (the FVs) also don't pose a problem
1844b725ae77Skettenis    because they are stored as 4 individual FP elements. */
1845b725ae77Skettenis 
1846b725ae77Skettenis static void
sh_register_convert_to_virtual(int regnum,struct type * type,char * from,char * to)1847b725ae77Skettenis sh_register_convert_to_virtual (int regnum, struct type *type,
1848b725ae77Skettenis 				char *from, char *to)
1849b725ae77Skettenis {
1850b725ae77Skettenis   if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
1851b725ae77Skettenis     {
1852b725ae77Skettenis       DOUBLEST val;
1853b725ae77Skettenis       floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
1854b725ae77Skettenis 			       from, &val);
1855b725ae77Skettenis       store_typed_floating (to, type, val);
1856b725ae77Skettenis     }
1857b725ae77Skettenis   else
1858b725ae77Skettenis     error
1859b725ae77Skettenis       ("sh_register_convert_to_virtual called with non DR register number");
1860b725ae77Skettenis }
1861b725ae77Skettenis 
1862b725ae77Skettenis static void
sh_register_convert_to_raw(struct type * type,int regnum,const void * from,void * to)1863b725ae77Skettenis sh_register_convert_to_raw (struct type *type, int regnum,
1864b725ae77Skettenis 			    const void *from, void *to)
1865b725ae77Skettenis {
1866b725ae77Skettenis   if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
1867b725ae77Skettenis     {
1868b725ae77Skettenis       DOUBLEST val = extract_typed_floating (from, type);
1869b725ae77Skettenis       floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword,
1870b725ae77Skettenis 				 &val, to);
1871b725ae77Skettenis     }
1872b725ae77Skettenis   else
1873b725ae77Skettenis     error ("sh_register_convert_to_raw called with non DR register number");
1874b725ae77Skettenis }
1875b725ae77Skettenis 
1876b725ae77Skettenis /* For vectors of 4 floating point registers. */
1877b725ae77Skettenis static int
fv_reg_base_num(int fv_regnum)1878b725ae77Skettenis fv_reg_base_num (int fv_regnum)
1879b725ae77Skettenis {
1880b725ae77Skettenis   int fp_regnum;
1881b725ae77Skettenis 
1882b725ae77Skettenis   fp_regnum = FP0_REGNUM + (fv_regnum - FV0_REGNUM) * 4;
1883b725ae77Skettenis   return fp_regnum;
1884b725ae77Skettenis }
1885b725ae77Skettenis 
1886b725ae77Skettenis /* For double precision floating point registers, i.e 2 fp regs.*/
1887b725ae77Skettenis static int
dr_reg_base_num(int dr_regnum)1888b725ae77Skettenis dr_reg_base_num (int dr_regnum)
1889b725ae77Skettenis {
1890b725ae77Skettenis   int fp_regnum;
1891b725ae77Skettenis 
1892b725ae77Skettenis   fp_regnum = FP0_REGNUM + (dr_regnum - DR0_REGNUM) * 2;
1893b725ae77Skettenis   return fp_regnum;
1894b725ae77Skettenis }
1895b725ae77Skettenis 
1896b725ae77Skettenis static void
sh_pseudo_register_read(struct gdbarch * gdbarch,struct regcache * regcache,int reg_nr,void * buffer)1897b725ae77Skettenis sh_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
1898b725ae77Skettenis 			 int reg_nr, void *buffer)
1899b725ae77Skettenis {
1900b725ae77Skettenis   int base_regnum, portion;
1901b725ae77Skettenis   char temp_buffer[MAX_REGISTER_SIZE];
1902b725ae77Skettenis 
190363addd46Skettenis   if (reg_nr == PSEUDO_BANK_REGNUM)
190463addd46Skettenis     regcache_raw_read (regcache, BANK_REGNUM, buffer);
190563addd46Skettenis   else
1906b725ae77Skettenis   if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
1907b725ae77Skettenis     {
1908b725ae77Skettenis       base_regnum = dr_reg_base_num (reg_nr);
1909b725ae77Skettenis 
1910b725ae77Skettenis       /* Build the value in the provided buffer. */
1911b725ae77Skettenis       /* Read the real regs for which this one is an alias.  */
1912b725ae77Skettenis       for (portion = 0; portion < 2; portion++)
1913b725ae77Skettenis 	regcache_raw_read (regcache, base_regnum + portion,
1914b725ae77Skettenis 			   (temp_buffer
1915b725ae77Skettenis 			    + register_size (gdbarch,
1916b725ae77Skettenis 					     base_regnum) * portion));
1917b725ae77Skettenis       /* We must pay attention to the endiannes. */
1918b725ae77Skettenis       sh_register_convert_to_virtual (reg_nr,
1919b725ae77Skettenis 				      gdbarch_register_type (gdbarch, reg_nr),
1920b725ae77Skettenis 				      temp_buffer, buffer);
1921b725ae77Skettenis     }
1922b725ae77Skettenis   else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
1923b725ae77Skettenis     {
1924b725ae77Skettenis       base_regnum = fv_reg_base_num (reg_nr);
1925b725ae77Skettenis 
1926b725ae77Skettenis       /* Read the real regs for which this one is an alias.  */
1927b725ae77Skettenis       for (portion = 0; portion < 4; portion++)
1928b725ae77Skettenis 	regcache_raw_read (regcache, base_regnum + portion,
1929b725ae77Skettenis 			   ((char *) buffer
1930b725ae77Skettenis 			    + register_size (gdbarch,
1931b725ae77Skettenis 					     base_regnum) * portion));
1932b725ae77Skettenis     }
1933b725ae77Skettenis }
1934b725ae77Skettenis 
1935b725ae77Skettenis static void
sh_pseudo_register_write(struct gdbarch * gdbarch,struct regcache * regcache,int reg_nr,const void * buffer)1936b725ae77Skettenis sh_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
1937b725ae77Skettenis 			  int reg_nr, const void *buffer)
1938b725ae77Skettenis {
1939b725ae77Skettenis   int base_regnum, portion;
1940b725ae77Skettenis   char temp_buffer[MAX_REGISTER_SIZE];
1941b725ae77Skettenis 
194263addd46Skettenis   if (reg_nr == PSEUDO_BANK_REGNUM)
194363addd46Skettenis     {
194463addd46Skettenis       /* When the bank register is written to, the whole register bank
194563addd46Skettenis          is switched and all values in the bank registers must be read
194663addd46Skettenis 	 from the target/sim again. We're just invalidating the regcache
194763addd46Skettenis 	 so that a re-read happens next time it's necessary.  */
194863addd46Skettenis       int bregnum;
194963addd46Skettenis 
195063addd46Skettenis       regcache_raw_write (regcache, BANK_REGNUM, buffer);
195163addd46Skettenis       for (bregnum = R0_BANK0_REGNUM; bregnum < MACLB_REGNUM; ++bregnum)
195263addd46Skettenis         set_register_cached (bregnum, 0);
195363addd46Skettenis     }
195463addd46Skettenis   else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM)
1955b725ae77Skettenis     {
1956b725ae77Skettenis       base_regnum = dr_reg_base_num (reg_nr);
1957b725ae77Skettenis 
1958b725ae77Skettenis       /* We must pay attention to the endiannes. */
1959b725ae77Skettenis       sh_register_convert_to_raw (gdbarch_register_type (gdbarch, reg_nr),
1960b725ae77Skettenis 				  reg_nr, buffer, temp_buffer);
1961b725ae77Skettenis 
1962b725ae77Skettenis       /* Write the real regs for which this one is an alias.  */
1963b725ae77Skettenis       for (portion = 0; portion < 2; portion++)
1964b725ae77Skettenis 	regcache_raw_write (regcache, base_regnum + portion,
1965b725ae77Skettenis 			    (temp_buffer
1966b725ae77Skettenis 			     + register_size (gdbarch,
1967b725ae77Skettenis 					      base_regnum) * portion));
1968b725ae77Skettenis     }
1969b725ae77Skettenis   else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM)
1970b725ae77Skettenis     {
1971b725ae77Skettenis       base_regnum = fv_reg_base_num (reg_nr);
1972b725ae77Skettenis 
1973b725ae77Skettenis       /* Write the real regs for which this one is an alias.  */
1974b725ae77Skettenis       for (portion = 0; portion < 4; portion++)
1975b725ae77Skettenis 	regcache_raw_write (regcache, base_regnum + portion,
1976b725ae77Skettenis 			    ((char *) buffer
1977b725ae77Skettenis 			     + register_size (gdbarch,
1978b725ae77Skettenis 					      base_regnum) * portion));
1979b725ae77Skettenis     }
1980b725ae77Skettenis }
1981b725ae77Skettenis 
1982b725ae77Skettenis /* Floating point vector of 4 float registers. */
1983b725ae77Skettenis static void
do_fv_register_info(struct gdbarch * gdbarch,struct ui_file * file,int fv_regnum)1984b725ae77Skettenis do_fv_register_info (struct gdbarch *gdbarch, struct ui_file *file,
1985b725ae77Skettenis 		     int fv_regnum)
1986b725ae77Skettenis {
1987b725ae77Skettenis   int first_fp_reg_num = fv_reg_base_num (fv_regnum);
1988b725ae77Skettenis   fprintf_filtered (file, "fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
1989b725ae77Skettenis 		    fv_regnum - FV0_REGNUM,
1990b725ae77Skettenis 		    (int) read_register (first_fp_reg_num),
1991b725ae77Skettenis 		    (int) read_register (first_fp_reg_num + 1),
1992b725ae77Skettenis 		    (int) read_register (first_fp_reg_num + 2),
1993b725ae77Skettenis 		    (int) read_register (first_fp_reg_num + 3));
1994b725ae77Skettenis }
1995b725ae77Skettenis 
1996b725ae77Skettenis /* Double precision registers. */
1997b725ae77Skettenis static void
do_dr_register_info(struct gdbarch * gdbarch,struct ui_file * file,int dr_regnum)1998b725ae77Skettenis do_dr_register_info (struct gdbarch *gdbarch, struct ui_file *file,
1999b725ae77Skettenis 		     int dr_regnum)
2000b725ae77Skettenis {
2001b725ae77Skettenis   int first_fp_reg_num = dr_reg_base_num (dr_regnum);
2002b725ae77Skettenis 
2003b725ae77Skettenis   fprintf_filtered (file, "dr%d\t0x%08x%08x\n",
2004b725ae77Skettenis 		    dr_regnum - DR0_REGNUM,
2005b725ae77Skettenis 		    (int) read_register (first_fp_reg_num),
2006b725ae77Skettenis 		    (int) read_register (first_fp_reg_num + 1));
2007b725ae77Skettenis }
200863addd46Skettenis static void
do_bank_register_info(struct gdbarch * gdbarch,struct ui_file * file)200963addd46Skettenis do_bank_register_info (struct gdbarch *gdbarch, struct ui_file *file)
201063addd46Skettenis {
201163addd46Skettenis   fprintf_filtered (file, "bank           %d\n",
201263addd46Skettenis 		    (int) read_register (BANK_REGNUM));
201363addd46Skettenis }
2014b725ae77Skettenis 
2015b725ae77Skettenis static void
sh_print_pseudo_register(struct gdbarch * gdbarch,struct ui_file * file,int regnum)2016b725ae77Skettenis sh_print_pseudo_register (struct gdbarch *gdbarch, struct ui_file *file,
2017b725ae77Skettenis 			  int regnum)
2018b725ae77Skettenis {
2019b725ae77Skettenis   if (regnum < NUM_REGS || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
2020b725ae77Skettenis     internal_error (__FILE__, __LINE__,
2021b725ae77Skettenis 		    "Invalid pseudo register number %d\n", regnum);
202263addd46Skettenis   else if (regnum == PSEUDO_BANK_REGNUM)
202363addd46Skettenis     do_bank_register_info (gdbarch, file);
2024b725ae77Skettenis   else if (regnum >= DR0_REGNUM && regnum <= DR_LAST_REGNUM)
2025b725ae77Skettenis     do_dr_register_info (gdbarch, file, regnum);
2026b725ae77Skettenis   else if (regnum >= FV0_REGNUM && regnum <= FV_LAST_REGNUM)
2027b725ae77Skettenis     do_fv_register_info (gdbarch, file, regnum);
2028b725ae77Skettenis }
2029b725ae77Skettenis 
2030b725ae77Skettenis static void
sh_do_fp_register(struct gdbarch * gdbarch,struct ui_file * file,int regnum)2031b725ae77Skettenis sh_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
2032b725ae77Skettenis {				/* do values for FP (float) regs */
2033b725ae77Skettenis   char *raw_buffer;
2034b725ae77Skettenis   double flt;			/* double extracted from raw hex data */
2035b725ae77Skettenis   int inv;
2036b725ae77Skettenis   int j;
2037b725ae77Skettenis 
2038b725ae77Skettenis   /* Allocate space for the float. */
2039b725ae77Skettenis   raw_buffer = (char *) alloca (register_size (gdbarch, FP0_REGNUM));
2040b725ae77Skettenis 
2041b725ae77Skettenis   /* Get the data in raw format.  */
2042b725ae77Skettenis   if (!frame_register_read (get_selected_frame (), regnum, raw_buffer))
2043b725ae77Skettenis     error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
2044b725ae77Skettenis 
2045b725ae77Skettenis   /* Get the register as a number */
2046b725ae77Skettenis   flt = unpack_double (builtin_type_float, raw_buffer, &inv);
2047b725ae77Skettenis 
2048b725ae77Skettenis   /* Print the name and some spaces. */
2049b725ae77Skettenis   fputs_filtered (REGISTER_NAME (regnum), file);
2050b725ae77Skettenis   print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
2051b725ae77Skettenis 
2052b725ae77Skettenis   /* Print the value. */
2053b725ae77Skettenis   if (inv)
2054b725ae77Skettenis     fprintf_filtered (file, "<invalid float>");
2055b725ae77Skettenis   else
2056b725ae77Skettenis     fprintf_filtered (file, "%-10.9g", flt);
2057b725ae77Skettenis 
2058b725ae77Skettenis   /* Print the fp register as hex. */
2059b725ae77Skettenis   fprintf_filtered (file, "\t(raw 0x");
2060b725ae77Skettenis   for (j = 0; j < register_size (gdbarch, regnum); j++)
2061b725ae77Skettenis     {
2062b725ae77Skettenis       int idx = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
2063b725ae77Skettenis 		 ? j
2064b725ae77Skettenis 		 : register_size (gdbarch, regnum) - 1 - j);
2065b725ae77Skettenis       fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]);
2066b725ae77Skettenis     }
2067b725ae77Skettenis   fprintf_filtered (file, ")");
2068b725ae77Skettenis   fprintf_filtered (file, "\n");
2069b725ae77Skettenis }
2070b725ae77Skettenis 
2071b725ae77Skettenis static void
sh_do_register(struct gdbarch * gdbarch,struct ui_file * file,int regnum)2072b725ae77Skettenis sh_do_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
2073b725ae77Skettenis {
2074b725ae77Skettenis   char raw_buffer[MAX_REGISTER_SIZE];
2075b725ae77Skettenis 
2076b725ae77Skettenis   fputs_filtered (REGISTER_NAME (regnum), file);
2077b725ae77Skettenis   print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
2078b725ae77Skettenis 
2079b725ae77Skettenis   /* Get the data in raw format.  */
2080b725ae77Skettenis   if (!frame_register_read (get_selected_frame (), regnum, raw_buffer))
2081b725ae77Skettenis     fprintf_filtered (file, "*value not available*\n");
2082b725ae77Skettenis 
2083b725ae77Skettenis   val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
2084b725ae77Skettenis 	     file, 'x', 1, 0, Val_pretty_default);
2085b725ae77Skettenis   fprintf_filtered (file, "\t");
2086b725ae77Skettenis   val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
2087b725ae77Skettenis 	     file, 0, 1, 0, Val_pretty_default);
2088b725ae77Skettenis   fprintf_filtered (file, "\n");
2089b725ae77Skettenis }
2090b725ae77Skettenis 
2091b725ae77Skettenis static void
sh_print_register(struct gdbarch * gdbarch,struct ui_file * file,int regnum)2092b725ae77Skettenis sh_print_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
2093b725ae77Skettenis {
2094b725ae77Skettenis   if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
2095b725ae77Skettenis     internal_error (__FILE__, __LINE__,
2096b725ae77Skettenis 		    "Invalid register number %d\n", regnum);
2097b725ae77Skettenis 
2098b725ae77Skettenis   else if (regnum >= 0 && regnum < NUM_REGS)
2099b725ae77Skettenis     {
2100b725ae77Skettenis       if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
2101b725ae77Skettenis 	  TYPE_CODE_FLT)
2102b725ae77Skettenis 	sh_do_fp_register (gdbarch, file, regnum);	/* FP regs */
2103b725ae77Skettenis       else
2104b725ae77Skettenis 	sh_do_register (gdbarch, file, regnum);	/* All other regs */
2105b725ae77Skettenis     }
2106b725ae77Skettenis 
2107b725ae77Skettenis   else if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
2108b725ae77Skettenis     {
2109b725ae77Skettenis       sh_print_pseudo_register (gdbarch, file, regnum);
2110b725ae77Skettenis     }
2111b725ae77Skettenis }
2112b725ae77Skettenis 
2113b725ae77Skettenis static void
sh_print_registers_info(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,int regnum,int fpregs)2114b725ae77Skettenis sh_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
2115b725ae77Skettenis 			 struct frame_info *frame, int regnum, int fpregs)
2116b725ae77Skettenis {
2117b725ae77Skettenis   if (regnum != -1)		/* do one specified register */
2118b725ae77Skettenis     {
2119b725ae77Skettenis       if (*(REGISTER_NAME (regnum)) == '\0')
2120b725ae77Skettenis 	error ("Not a valid register for the current processor type");
2121b725ae77Skettenis 
2122b725ae77Skettenis       sh_print_register (gdbarch, file, regnum);
2123b725ae77Skettenis     }
2124b725ae77Skettenis   else
2125b725ae77Skettenis     /* do all (or most) registers */
2126b725ae77Skettenis     {
212763addd46Skettenis       for (regnum = 0; regnum < NUM_REGS; ++regnum)
2128b725ae77Skettenis 	{
2129b725ae77Skettenis 	  /* If the register name is empty, it is undefined for this
2130b725ae77Skettenis 	     processor, so don't display anything.  */
2131b725ae77Skettenis 	  if (REGISTER_NAME (regnum) == NULL
2132b725ae77Skettenis 	      || *(REGISTER_NAME (regnum)) == '\0')
2133b725ae77Skettenis 	    continue;
2134b725ae77Skettenis 
2135b725ae77Skettenis 	  if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
2136b725ae77Skettenis 	      TYPE_CODE_FLT)
2137b725ae77Skettenis 	    {
2138b725ae77Skettenis 	      /* true for "INFO ALL-REGISTERS" command */
213963addd46Skettenis 	      if (fpregs)
2140b725ae77Skettenis 		sh_do_fp_register (gdbarch, file, regnum);	/* FP regs */
2141b725ae77Skettenis 	    }
2142b725ae77Skettenis 	  else
2143b725ae77Skettenis 	    sh_do_register (gdbarch, file, regnum);	/* All other regs */
2144b725ae77Skettenis 	}
214563addd46Skettenis 
214663addd46Skettenis       if (regnum == PSEUDO_BANK_REGNUM
214763addd46Skettenis       	  && REGISTER_NAME (regnum)
214863addd46Skettenis 	  && *REGISTER_NAME (regnum))
214963addd46Skettenis 	sh_print_pseudo_register (gdbarch, file, regnum++);
2150b725ae77Skettenis 
2151b725ae77Skettenis       if (fpregs)
2152b725ae77Skettenis 	while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
2153b725ae77Skettenis 	  {
2154b725ae77Skettenis 	    sh_print_pseudo_register (gdbarch, file, regnum);
2155b725ae77Skettenis 	    regnum++;
2156b725ae77Skettenis 	  }
2157b725ae77Skettenis     }
2158b725ae77Skettenis }
2159b725ae77Skettenis 
2160b725ae77Skettenis /* Fetch (and possibly build) an appropriate link_map_offsets structure
2161b725ae77Skettenis    for native i386 linux targets using the struct offsets defined in
2162b725ae77Skettenis    link.h (but without actual reference to that file).
2163b725ae77Skettenis 
2164b725ae77Skettenis    This makes it possible to access i386-linux shared libraries from
2165b725ae77Skettenis    a gdb that was not built on an i386-linux host (for cross debugging).
2166b725ae77Skettenis    */
2167b725ae77Skettenis 
2168b725ae77Skettenis struct link_map_offsets *
sh_linux_svr4_fetch_link_map_offsets(void)2169b725ae77Skettenis sh_linux_svr4_fetch_link_map_offsets (void)
2170b725ae77Skettenis {
2171b725ae77Skettenis   static struct link_map_offsets lmo;
2172b725ae77Skettenis   static struct link_map_offsets *lmp = 0;
2173b725ae77Skettenis 
2174b725ae77Skettenis   if (lmp == 0)
2175b725ae77Skettenis     {
2176b725ae77Skettenis       lmp = &lmo;
2177b725ae77Skettenis 
2178b725ae77Skettenis       lmo.r_debug_size = 8;	/* 20 not actual size but all we need */
2179b725ae77Skettenis 
2180b725ae77Skettenis       lmo.r_map_offset = 4;
2181b725ae77Skettenis       lmo.r_map_size = 4;
2182b725ae77Skettenis 
2183b725ae77Skettenis       lmo.link_map_size = 20;	/* 552 not actual size but all we need */
2184b725ae77Skettenis 
2185b725ae77Skettenis       lmo.l_addr_offset = 0;
2186b725ae77Skettenis       lmo.l_addr_size = 4;
2187b725ae77Skettenis 
2188b725ae77Skettenis       lmo.l_name_offset = 4;
2189b725ae77Skettenis       lmo.l_name_size = 4;
2190b725ae77Skettenis 
2191b725ae77Skettenis       lmo.l_next_offset = 12;
2192b725ae77Skettenis       lmo.l_next_size = 4;
2193b725ae77Skettenis 
2194b725ae77Skettenis       lmo.l_prev_offset = 16;
2195b725ae77Skettenis       lmo.l_prev_size = 4;
2196b725ae77Skettenis     }
2197b725ae77Skettenis 
2198b725ae77Skettenis   return lmp;
2199b725ae77Skettenis }
2200b725ae77Skettenis 
2201b725ae77Skettenis static int
sh_dsp_register_sim_regno(int nr)2202b725ae77Skettenis sh_dsp_register_sim_regno (int nr)
2203b725ae77Skettenis {
2204b725ae77Skettenis   if (legacy_register_sim_regno (nr) < 0)
2205b725ae77Skettenis     return legacy_register_sim_regno (nr);
2206b725ae77Skettenis   if (nr >= DSR_REGNUM && nr <= Y1_REGNUM)
2207b725ae77Skettenis     return nr - DSR_REGNUM + SIM_SH_DSR_REGNUM;
2208b725ae77Skettenis   if (nr == MOD_REGNUM)
2209b725ae77Skettenis     return SIM_SH_MOD_REGNUM;
2210b725ae77Skettenis   if (nr == RS_REGNUM)
2211b725ae77Skettenis     return SIM_SH_RS_REGNUM;
2212b725ae77Skettenis   if (nr == RE_REGNUM)
2213b725ae77Skettenis     return SIM_SH_RE_REGNUM;
2214b725ae77Skettenis   if (nr >= DSP_R0_BANK_REGNUM && nr <= DSP_R7_BANK_REGNUM)
2215b725ae77Skettenis     return nr - DSP_R0_BANK_REGNUM + SIM_SH_R0_BANK_REGNUM;
2216b725ae77Skettenis   return nr;
2217b725ae77Skettenis }
2218b725ae77Skettenis 
2219*2f050487Smiod #ifdef notyet
222063addd46Skettenis static int
sh_sh2a_register_sim_regno(int nr)222163addd46Skettenis sh_sh2a_register_sim_regno (int nr)
222263addd46Skettenis {
222363addd46Skettenis   switch (nr)
222463addd46Skettenis     {
222563addd46Skettenis       case TBR_REGNUM:
222663addd46Skettenis         return SIM_SH_TBR_REGNUM;
222763addd46Skettenis       case IBNR_REGNUM:
222863addd46Skettenis         return SIM_SH_IBNR_REGNUM;
222963addd46Skettenis       case IBCR_REGNUM:
223063addd46Skettenis         return SIM_SH_IBCR_REGNUM;
223163addd46Skettenis       case BANK_REGNUM:
223263addd46Skettenis         return SIM_SH_BANK_REGNUM;
223363addd46Skettenis       case MACLB_REGNUM:
223463addd46Skettenis         return SIM_SH_BANK_MACL_REGNUM;
223563addd46Skettenis       case GBRB_REGNUM:
223663addd46Skettenis         return SIM_SH_BANK_GBR_REGNUM;
223763addd46Skettenis       case PRB_REGNUM:
223863addd46Skettenis         return SIM_SH_BANK_PR_REGNUM;
223963addd46Skettenis       case IVNB_REGNUM:
224063addd46Skettenis         return SIM_SH_BANK_IVN_REGNUM;
224163addd46Skettenis       case MACHB_REGNUM:
224263addd46Skettenis         return SIM_SH_BANK_MACH_REGNUM;
224363addd46Skettenis       default:
224463addd46Skettenis         break;
224563addd46Skettenis     }
224663addd46Skettenis   return legacy_register_sim_regno (nr);
224763addd46Skettenis }
2248*2f050487Smiod #endif
224963addd46Skettenis 
2250b725ae77Skettenis static struct sh_frame_cache *
sh_alloc_frame_cache(void)2251b725ae77Skettenis sh_alloc_frame_cache (void)
2252b725ae77Skettenis {
2253b725ae77Skettenis   struct sh_frame_cache *cache;
2254b725ae77Skettenis   int i;
2255b725ae77Skettenis 
2256b725ae77Skettenis   cache = FRAME_OBSTACK_ZALLOC (struct sh_frame_cache);
2257b725ae77Skettenis 
2258b725ae77Skettenis   /* Base address.  */
2259b725ae77Skettenis   cache->base = 0;
2260b725ae77Skettenis   cache->saved_sp = 0;
2261b725ae77Skettenis   cache->sp_offset = 0;
2262b725ae77Skettenis   cache->pc = 0;
2263b725ae77Skettenis 
2264b725ae77Skettenis   /* Frameless until proven otherwise.  */
2265b725ae77Skettenis   cache->uses_fp = 0;
2266b725ae77Skettenis 
2267b725ae77Skettenis   /* Saved registers.  We initialize these to -1 since zero is a valid
2268b725ae77Skettenis      offset (that's where fp is supposed to be stored).  */
2269b725ae77Skettenis   for (i = 0; i < SH_NUM_REGS; i++)
2270b725ae77Skettenis     {
2271b725ae77Skettenis       cache->saved_regs[i] = -1;
2272b725ae77Skettenis     }
2273b725ae77Skettenis 
2274b725ae77Skettenis   return cache;
2275b725ae77Skettenis }
2276b725ae77Skettenis 
2277b725ae77Skettenis static struct sh_frame_cache *
sh_frame_cache(struct frame_info * next_frame,void ** this_cache)2278b725ae77Skettenis sh_frame_cache (struct frame_info *next_frame, void **this_cache)
2279b725ae77Skettenis {
2280b725ae77Skettenis   struct sh_frame_cache *cache;
2281b725ae77Skettenis   CORE_ADDR current_pc;
2282b725ae77Skettenis   int i;
2283b725ae77Skettenis 
2284b725ae77Skettenis   if (*this_cache)
2285b725ae77Skettenis     return *this_cache;
2286b725ae77Skettenis 
2287b725ae77Skettenis   cache = sh_alloc_frame_cache ();
2288b725ae77Skettenis   *this_cache = cache;
2289b725ae77Skettenis 
2290b725ae77Skettenis   /* In principle, for normal frames, fp holds the frame pointer,
2291b725ae77Skettenis      which holds the base address for the current stack frame.
2292b725ae77Skettenis      However, for functions that don't need it, the frame pointer is
2293b725ae77Skettenis      optional.  For these "frameless" functions the frame pointer is
2294b725ae77Skettenis      actually the frame pointer of the calling frame. */
2295b725ae77Skettenis   cache->base = frame_unwind_register_unsigned (next_frame, FP_REGNUM);
2296b725ae77Skettenis   if (cache->base == 0)
2297b725ae77Skettenis     return cache;
2298b725ae77Skettenis 
2299b725ae77Skettenis   cache->pc = frame_func_unwind (next_frame);
2300b725ae77Skettenis   current_pc = frame_pc_unwind (next_frame);
2301b725ae77Skettenis   if (cache->pc != 0)
2302b725ae77Skettenis     sh_analyze_prologue (cache->pc, current_pc, cache);
2303b725ae77Skettenis 
2304b725ae77Skettenis   if (!cache->uses_fp)
2305b725ae77Skettenis     {
2306b725ae77Skettenis       /* We didn't find a valid frame, which means that CACHE->base
2307b725ae77Skettenis          currently holds the frame pointer for our calling frame.  If
2308b725ae77Skettenis          we're at the start of a function, or somewhere half-way its
2309b725ae77Skettenis          prologue, the function's frame probably hasn't been fully
2310b725ae77Skettenis          setup yet.  Try to reconstruct the base address for the stack
2311b725ae77Skettenis          frame by looking at the stack pointer.  For truly "frameless"
2312b725ae77Skettenis          functions this might work too.  */
2313b725ae77Skettenis       cache->base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
2314b725ae77Skettenis     }
2315b725ae77Skettenis 
2316b725ae77Skettenis   /* Now that we have the base address for the stack frame we can
2317b725ae77Skettenis      calculate the value of sp in the calling frame.  */
2318b725ae77Skettenis   cache->saved_sp = cache->base + cache->sp_offset;
2319b725ae77Skettenis 
2320b725ae77Skettenis   /* Adjust all the saved registers such that they contain addresses
2321b725ae77Skettenis      instead of offsets.  */
2322b725ae77Skettenis   for (i = 0; i < SH_NUM_REGS; i++)
2323b725ae77Skettenis     if (cache->saved_regs[i] != -1)
2324b725ae77Skettenis       cache->saved_regs[i] = cache->saved_sp - cache->saved_regs[i] - 4;
2325b725ae77Skettenis 
2326b725ae77Skettenis   return cache;
2327b725ae77Skettenis }
2328b725ae77Skettenis 
2329b725ae77Skettenis static void
sh_frame_prev_register(struct frame_info * next_frame,void ** this_cache,int regnum,int * optimizedp,enum lval_type * lvalp,CORE_ADDR * addrp,int * realnump,void * valuep)2330b725ae77Skettenis sh_frame_prev_register (struct frame_info *next_frame, void **this_cache,
2331b725ae77Skettenis 			int regnum, int *optimizedp,
2332b725ae77Skettenis 			enum lval_type *lvalp, CORE_ADDR *addrp,
2333b725ae77Skettenis 			int *realnump, void *valuep)
2334b725ae77Skettenis {
2335b725ae77Skettenis   struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
2336b725ae77Skettenis 
2337b725ae77Skettenis   gdb_assert (regnum >= 0);
2338b725ae77Skettenis 
2339b725ae77Skettenis   if (regnum == SP_REGNUM && cache->saved_sp)
2340b725ae77Skettenis     {
2341b725ae77Skettenis       *optimizedp = 0;
2342b725ae77Skettenis       *lvalp = not_lval;
2343b725ae77Skettenis       *addrp = 0;
2344b725ae77Skettenis       *realnump = -1;
2345b725ae77Skettenis       if (valuep)
2346b725ae77Skettenis 	{
2347b725ae77Skettenis 	  /* Store the value.  */
2348b725ae77Skettenis 	  store_unsigned_integer (valuep, 4, cache->saved_sp);
2349b725ae77Skettenis 	}
2350b725ae77Skettenis       return;
2351b725ae77Skettenis     }
2352b725ae77Skettenis 
2353b725ae77Skettenis   /* The PC of the previous frame is stored in the PR register of
2354b725ae77Skettenis      the current frame.  Frob regnum so that we pull the value from
2355b725ae77Skettenis      the correct place.  */
2356b725ae77Skettenis   if (regnum == PC_REGNUM)
2357b725ae77Skettenis     regnum = PR_REGNUM;
2358b725ae77Skettenis 
2359b725ae77Skettenis   if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1)
2360b725ae77Skettenis     {
2361b725ae77Skettenis       *optimizedp = 0;
2362b725ae77Skettenis       *lvalp = lval_memory;
2363b725ae77Skettenis       *addrp = cache->saved_regs[regnum];
2364b725ae77Skettenis       *realnump = -1;
2365b725ae77Skettenis       if (valuep)
2366b725ae77Skettenis 	{
2367b725ae77Skettenis 	  /* Read the value in from memory.  */
2368b725ae77Skettenis 	  read_memory (*addrp, valuep,
2369b725ae77Skettenis 		       register_size (current_gdbarch, regnum));
2370b725ae77Skettenis 	}
2371b725ae77Skettenis       return;
2372b725ae77Skettenis     }
2373b725ae77Skettenis 
2374b725ae77Skettenis   frame_register_unwind (next_frame, regnum,
2375b725ae77Skettenis 			 optimizedp, lvalp, addrp, realnump, valuep);
2376b725ae77Skettenis }
2377b725ae77Skettenis 
2378b725ae77Skettenis static void
sh_frame_this_id(struct frame_info * next_frame,void ** this_cache,struct frame_id * this_id)2379b725ae77Skettenis sh_frame_this_id (struct frame_info *next_frame, void **this_cache,
2380b725ae77Skettenis 		  struct frame_id *this_id)
2381b725ae77Skettenis {
2382b725ae77Skettenis   struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
2383b725ae77Skettenis 
2384b725ae77Skettenis   /* This marks the outermost frame.  */
2385b725ae77Skettenis   if (cache->base == 0)
2386b725ae77Skettenis     return;
2387b725ae77Skettenis 
2388b725ae77Skettenis   *this_id = frame_id_build (cache->saved_sp, cache->pc);
2389b725ae77Skettenis }
2390b725ae77Skettenis 
2391b725ae77Skettenis static const struct frame_unwind sh_frame_unwind = {
2392b725ae77Skettenis   NORMAL_FRAME,
2393b725ae77Skettenis   sh_frame_this_id,
2394b725ae77Skettenis   sh_frame_prev_register
2395b725ae77Skettenis };
2396b725ae77Skettenis 
2397b725ae77Skettenis static const struct frame_unwind *
sh_frame_sniffer(struct frame_info * next_frame)2398b725ae77Skettenis sh_frame_sniffer (struct frame_info *next_frame)
2399b725ae77Skettenis {
2400b725ae77Skettenis   return &sh_frame_unwind;
2401b725ae77Skettenis }
2402b725ae77Skettenis 
2403b725ae77Skettenis static CORE_ADDR
sh_unwind_sp(struct gdbarch * gdbarch,struct frame_info * next_frame)2404b725ae77Skettenis sh_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
2405b725ae77Skettenis {
2406b725ae77Skettenis   return frame_unwind_register_unsigned (next_frame, SP_REGNUM);
2407b725ae77Skettenis }
2408b725ae77Skettenis 
2409b725ae77Skettenis static CORE_ADDR
sh_unwind_pc(struct gdbarch * gdbarch,struct frame_info * next_frame)2410b725ae77Skettenis sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
2411b725ae77Skettenis {
2412b725ae77Skettenis   return frame_unwind_register_unsigned (next_frame, PC_REGNUM);
2413b725ae77Skettenis }
2414b725ae77Skettenis 
2415b725ae77Skettenis static struct frame_id
sh_unwind_dummy_id(struct gdbarch * gdbarch,struct frame_info * next_frame)2416b725ae77Skettenis sh_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
2417b725ae77Skettenis {
2418b725ae77Skettenis   return frame_id_build (sh_unwind_sp (gdbarch, next_frame),
2419b725ae77Skettenis 			 frame_pc_unwind (next_frame));
2420b725ae77Skettenis }
2421b725ae77Skettenis 
2422b725ae77Skettenis static CORE_ADDR
sh_frame_base_address(struct frame_info * next_frame,void ** this_cache)2423b725ae77Skettenis sh_frame_base_address (struct frame_info *next_frame, void **this_cache)
2424b725ae77Skettenis {
2425b725ae77Skettenis   struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache);
2426b725ae77Skettenis 
2427b725ae77Skettenis   return cache->base;
2428b725ae77Skettenis }
2429b725ae77Skettenis 
2430b725ae77Skettenis static const struct frame_base sh_frame_base = {
2431b725ae77Skettenis   &sh_frame_unwind,
2432b725ae77Skettenis   sh_frame_base_address,
2433b725ae77Skettenis   sh_frame_base_address,
2434b725ae77Skettenis   sh_frame_base_address
2435b725ae77Skettenis };
2436b725ae77Skettenis 
2437b725ae77Skettenis /* The epilogue is defined here as the area at the end of a function,
2438b725ae77Skettenis    either on the `ret' instruction itself or after an instruction which
2439b725ae77Skettenis    destroys the function's stack frame. */
2440b725ae77Skettenis static int
sh_in_function_epilogue_p(struct gdbarch * gdbarch,CORE_ADDR pc)2441b725ae77Skettenis sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
2442b725ae77Skettenis {
2443b725ae77Skettenis   CORE_ADDR func_addr = 0, func_end = 0;
2444b725ae77Skettenis 
2445b725ae77Skettenis   if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
2446b725ae77Skettenis     {
2447b725ae77Skettenis       ULONGEST inst;
2448b725ae77Skettenis       /* The sh epilogue is max. 14 bytes long.  Give another 14 bytes
2449b725ae77Skettenis          for a nop and some fixed data (e.g. big offsets) which are
2450b725ae77Skettenis          unfortunately also treated as part of the function (which
2451b725ae77Skettenis          means, they are below func_end. */
2452b725ae77Skettenis       CORE_ADDR addr = func_end - 28;
2453b725ae77Skettenis       if (addr < func_addr + 4)
2454b725ae77Skettenis 	addr = func_addr + 4;
2455b725ae77Skettenis       if (pc < addr)
2456b725ae77Skettenis 	return 0;
2457b725ae77Skettenis 
2458b725ae77Skettenis       /* First search forward until hitting an rts. */
2459b725ae77Skettenis       while (addr < func_end
2460b725ae77Skettenis 	     && !IS_RTS (read_memory_unsigned_integer (addr, 2)))
2461b725ae77Skettenis 	addr += 2;
2462b725ae77Skettenis       if (addr >= func_end)
2463b725ae77Skettenis 	return 0;
2464b725ae77Skettenis 
2465b725ae77Skettenis       /* At this point we should find a mov.l @r15+,r14 instruction,
2466b725ae77Skettenis          either before or after the rts.  If not, then the function has
2467b725ae77Skettenis          probably no "normal" epilogue and we bail out here. */
2468b725ae77Skettenis       inst = read_memory_unsigned_integer (addr - 2, 2);
2469b725ae77Skettenis       if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2)))
2470b725ae77Skettenis 	addr -= 2;
2471b725ae77Skettenis       else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2)))
2472b725ae77Skettenis 	return 0;
2473b725ae77Skettenis 
2474b725ae77Skettenis       inst = read_memory_unsigned_integer (addr - 2, 2);
247563addd46Skettenis 
247663addd46Skettenis       /* Step over possible lds.l @r15+,macl. */
247763addd46Skettenis       if (IS_MACL_LDS (inst))
247863addd46Skettenis 	{
247963addd46Skettenis 	  addr -= 2;
248063addd46Skettenis 	  inst = read_memory_unsigned_integer (addr - 2, 2);
248163addd46Skettenis 	}
248263addd46Skettenis 
248363addd46Skettenis       /* Step over possible lds.l @r15+,pr. */
2484b725ae77Skettenis       if (IS_LDS (inst))
2485b725ae77Skettenis 	{
2486b725ae77Skettenis 	  addr -= 2;
2487b725ae77Skettenis 	  inst = read_memory_unsigned_integer (addr - 2, 2);
2488b725ae77Skettenis 	}
2489b725ae77Skettenis 
2490b725ae77Skettenis       /* Step over possible mov r14,r15. */
2491b725ae77Skettenis       if (IS_MOV_FP_SP (inst))
2492b725ae77Skettenis 	{
2493b725ae77Skettenis 	  addr -= 2;
2494b725ae77Skettenis 	  inst = read_memory_unsigned_integer (addr - 2, 2);
2495b725ae77Skettenis 	}
2496b725ae77Skettenis 
2497b725ae77Skettenis       /* Now check for FP adjustments, using add #imm,r14 or add rX, r14
2498b725ae77Skettenis          instructions. */
2499b725ae77Skettenis       while (addr > func_addr + 4
2500b725ae77Skettenis 	     && (IS_ADD_REG_TO_FP (inst) || IS_ADD_IMM_FP (inst)))
2501b725ae77Skettenis 	{
2502b725ae77Skettenis 	  addr -= 2;
2503b725ae77Skettenis 	  inst = read_memory_unsigned_integer (addr - 2, 2);
2504b725ae77Skettenis 	}
2505b725ae77Skettenis 
2506*2f050487Smiod #ifdef notyet
250763addd46Skettenis       /* On SH2a check if the previous instruction was perhaps a MOVI20.
250863addd46Skettenis          That's allowed for the epilogue.  */
250963addd46Skettenis       if ((gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a
251063addd46Skettenis            || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a_nofpu)
251163addd46Skettenis           && addr > func_addr + 6
251263addd46Skettenis 	  && IS_MOVI20 (read_memory_unsigned_integer (addr - 4, 2)))
251363addd46Skettenis 	addr -= 4;
2514*2f050487Smiod #endif
251563addd46Skettenis 
2516b725ae77Skettenis       if (pc >= addr)
2517b725ae77Skettenis 	return 1;
2518b725ae77Skettenis     }
2519b725ae77Skettenis   return 0;
2520b725ae77Skettenis }
2521b725ae77Skettenis 
2522b725ae77Skettenis static gdbarch_init_ftype sh_gdbarch_init;
2523b725ae77Skettenis 
2524b725ae77Skettenis static struct gdbarch *
sh_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)2525b725ae77Skettenis sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
2526b725ae77Skettenis {
2527b725ae77Skettenis   struct gdbarch *gdbarch;
2528b725ae77Skettenis 
2529b725ae77Skettenis   sh_show_regs = sh_generic_show_regs;
2530b725ae77Skettenis   switch (info.bfd_arch_info->mach)
2531b725ae77Skettenis     {
2532b725ae77Skettenis     case bfd_mach_sh2e:
2533b725ae77Skettenis       sh_show_regs = sh2e_show_regs;
2534b725ae77Skettenis       break;
2535*2f050487Smiod #ifdef notyet
253663addd46Skettenis     case bfd_mach_sh2a:
253763addd46Skettenis       sh_show_regs = sh2a_show_regs;
253863addd46Skettenis       break;
253963addd46Skettenis     case bfd_mach_sh2a_nofpu:
254063addd46Skettenis       sh_show_regs = sh2a_nofpu_show_regs;
254163addd46Skettenis       break;
2542*2f050487Smiod #endif
2543b725ae77Skettenis     case bfd_mach_sh_dsp:
2544b725ae77Skettenis       sh_show_regs = sh_dsp_show_regs;
2545b725ae77Skettenis       break;
2546b725ae77Skettenis 
2547b725ae77Skettenis     case bfd_mach_sh3:
2548b725ae77Skettenis       sh_show_regs = sh3_show_regs;
2549b725ae77Skettenis       break;
2550b725ae77Skettenis 
2551b725ae77Skettenis     case bfd_mach_sh3e:
2552b725ae77Skettenis       sh_show_regs = sh3e_show_regs;
2553b725ae77Skettenis       break;
2554b725ae77Skettenis 
2555b725ae77Skettenis     case bfd_mach_sh3_dsp:
2556b725ae77Skettenis     case bfd_mach_sh4al_dsp:
2557b725ae77Skettenis       sh_show_regs = sh3_dsp_show_regs;
2558b725ae77Skettenis       break;
2559b725ae77Skettenis 
2560b725ae77Skettenis     case bfd_mach_sh4:
2561b725ae77Skettenis     case bfd_mach_sh4a:
2562b725ae77Skettenis       sh_show_regs = sh4_show_regs;
2563b725ae77Skettenis       break;
2564b725ae77Skettenis 
2565b725ae77Skettenis     case bfd_mach_sh4_nofpu:
2566b725ae77Skettenis     case bfd_mach_sh4a_nofpu:
2567b725ae77Skettenis       sh_show_regs = sh4_nofpu_show_regs;
2568b725ae77Skettenis       break;
2569b725ae77Skettenis 
257063addd46Skettenis #if 0
2571b725ae77Skettenis     case bfd_mach_sh5:
2572b725ae77Skettenis       sh_show_regs = sh64_show_regs;
2573b725ae77Skettenis       /* SH5 is handled entirely in sh64-tdep.c */
2574b725ae77Skettenis       return sh64_gdbarch_init (info, arches);
257563addd46Skettenis #endif
2576b725ae77Skettenis     }
2577b725ae77Skettenis 
2578b725ae77Skettenis   /* If there is already a candidate, use it.  */
2579b725ae77Skettenis   arches = gdbarch_list_lookup_by_info (arches, &info);
2580b725ae77Skettenis   if (arches != NULL)
2581b725ae77Skettenis     return arches->gdbarch;
2582b725ae77Skettenis 
2583b725ae77Skettenis   /* None found, create a new architecture from the information
2584b725ae77Skettenis      provided. */
2585b725ae77Skettenis   gdbarch = gdbarch_alloc (&info, NULL);
2586b725ae77Skettenis 
2587b725ae77Skettenis   set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
2588b725ae77Skettenis   set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2589b725ae77Skettenis   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2590b725ae77Skettenis   set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2591b725ae77Skettenis   set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2592b725ae77Skettenis   set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2593b725ae77Skettenis   set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2594b725ae77Skettenis   set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2595b725ae77Skettenis 
2596b725ae77Skettenis   set_gdbarch_num_regs (gdbarch, SH_NUM_REGS);
2597b725ae77Skettenis   set_gdbarch_sp_regnum (gdbarch, 15);
2598b725ae77Skettenis   set_gdbarch_pc_regnum (gdbarch, 16);
2599b725ae77Skettenis   set_gdbarch_fp0_regnum (gdbarch, -1);
2600b725ae77Skettenis   set_gdbarch_num_pseudo_regs (gdbarch, 0);
2601b725ae77Skettenis 
2602b725ae77Skettenis   set_gdbarch_register_type (gdbarch, sh_default_register_type);
2603b725ae77Skettenis 
2604b725ae77Skettenis   set_gdbarch_print_registers_info (gdbarch, sh_print_registers_info);
2605b725ae77Skettenis 
2606b725ae77Skettenis   set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc);
2607b725ae77Skettenis 
2608b725ae77Skettenis   set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh);
2609b725ae77Skettenis   set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
2610b725ae77Skettenis 
2611b725ae77Skettenis   set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
2612b725ae77Skettenis 
261363addd46Skettenis   set_gdbarch_return_value (gdbarch, sh_return_value_nofpu);
261463addd46Skettenis   set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
261563addd46Skettenis 					    sh_extract_struct_value_address);
2616b725ae77Skettenis 
2617b725ae77Skettenis   set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
2618b725ae77Skettenis   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
2619b725ae77Skettenis 
2620b725ae77Skettenis   set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_nofpu);
2621b725ae77Skettenis 
2622b725ae77Skettenis   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
2623b725ae77Skettenis 
2624b725ae77Skettenis   set_gdbarch_frame_align (gdbarch, sh_frame_align);
2625b725ae77Skettenis   set_gdbarch_unwind_sp (gdbarch, sh_unwind_sp);
2626b725ae77Skettenis   set_gdbarch_unwind_pc (gdbarch, sh_unwind_pc);
2627b725ae77Skettenis   set_gdbarch_unwind_dummy_id (gdbarch, sh_unwind_dummy_id);
2628b725ae77Skettenis   frame_base_set_default (gdbarch, &sh_frame_base);
2629b725ae77Skettenis 
2630b725ae77Skettenis   set_gdbarch_in_function_epilogue_p (gdbarch, sh_in_function_epilogue_p);
2631b725ae77Skettenis 
2632b725ae77Skettenis   switch (info.bfd_arch_info->mach)
2633b725ae77Skettenis     {
2634b725ae77Skettenis     case bfd_mach_sh:
2635b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh_register_name);
2636b725ae77Skettenis       break;
2637b725ae77Skettenis 
2638b725ae77Skettenis     case bfd_mach_sh2:
2639b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh_register_name);
2640b725ae77Skettenis       break;
2641b725ae77Skettenis 
2642b725ae77Skettenis     case bfd_mach_sh2e:
2643b725ae77Skettenis       /* doubles on sh2e and sh3e are actually 4 byte. */
2644b725ae77Skettenis       set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2645b725ae77Skettenis 
2646b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh2e_register_name);
2647b725ae77Skettenis       set_gdbarch_register_type (gdbarch, sh_sh3e_register_type);
2648b725ae77Skettenis       set_gdbarch_fp0_regnum (gdbarch, 25);
264963addd46Skettenis       set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
2650b725ae77Skettenis       set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
2651b725ae77Skettenis       break;
2652b725ae77Skettenis 
2653*2f050487Smiod #ifdef notyet
265463addd46Skettenis     case bfd_mach_sh2a:
265563addd46Skettenis       set_gdbarch_register_name (gdbarch, sh_sh2a_register_name);
265663addd46Skettenis       set_gdbarch_register_type (gdbarch, sh_sh2a_register_type);
265763addd46Skettenis       set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno);
265863addd46Skettenis 
265963addd46Skettenis       set_gdbarch_fp0_regnum (gdbarch, 25);
266063addd46Skettenis       set_gdbarch_num_pseudo_regs (gdbarch, 9);
266163addd46Skettenis       set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
266263addd46Skettenis       set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
266363addd46Skettenis       set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
266463addd46Skettenis       set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
266563addd46Skettenis       break;
266663addd46Skettenis 
266763addd46Skettenis     case bfd_mach_sh2a_nofpu:
266863addd46Skettenis       set_gdbarch_register_name (gdbarch, sh_sh2a_nofpu_register_name);
266963addd46Skettenis       set_gdbarch_register_sim_regno (gdbarch, sh_sh2a_register_sim_regno);
267063addd46Skettenis 
267163addd46Skettenis       set_gdbarch_num_pseudo_regs (gdbarch, 1);
267263addd46Skettenis       set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
267363addd46Skettenis       set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
267463addd46Skettenis       break;
2675*2f050487Smiod #endif
267663addd46Skettenis 
2677b725ae77Skettenis     case bfd_mach_sh_dsp:
2678b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh_dsp_register_name);
2679b725ae77Skettenis       set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
2680b725ae77Skettenis       break;
2681b725ae77Skettenis 
2682b725ae77Skettenis     case bfd_mach_sh3:
2683b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh3_register_name);
2684b725ae77Skettenis       break;
2685b725ae77Skettenis 
2686b725ae77Skettenis     case bfd_mach_sh3e:
2687b725ae77Skettenis       /* doubles on sh2e and sh3e are actually 4 byte. */
2688b725ae77Skettenis       set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2689b725ae77Skettenis 
2690b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh3e_register_name);
2691b725ae77Skettenis       set_gdbarch_register_type (gdbarch, sh_sh3e_register_type);
2692b725ae77Skettenis       set_gdbarch_fp0_regnum (gdbarch, 25);
269363addd46Skettenis       set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
2694b725ae77Skettenis       set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
2695b725ae77Skettenis       break;
2696b725ae77Skettenis 
2697b725ae77Skettenis     case bfd_mach_sh3_dsp:
2698b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh3_dsp_register_name);
2699b725ae77Skettenis       set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
2700b725ae77Skettenis       break;
2701b725ae77Skettenis 
2702b725ae77Skettenis     case bfd_mach_sh4:
2703b725ae77Skettenis     case bfd_mach_sh4a:
2704b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh4_register_name);
2705b725ae77Skettenis       set_gdbarch_register_type (gdbarch, sh_sh4_register_type);
2706b725ae77Skettenis       set_gdbarch_fp0_regnum (gdbarch, 25);
270763addd46Skettenis       set_gdbarch_num_pseudo_regs (gdbarch, 13);
2708b725ae77Skettenis       set_gdbarch_pseudo_register_read (gdbarch, sh_pseudo_register_read);
2709b725ae77Skettenis       set_gdbarch_pseudo_register_write (gdbarch, sh_pseudo_register_write);
271063addd46Skettenis       set_gdbarch_return_value (gdbarch, sh_return_value_fpu);
2711b725ae77Skettenis       set_gdbarch_push_dummy_call (gdbarch, sh_push_dummy_call_fpu);
2712b725ae77Skettenis       break;
2713b725ae77Skettenis 
2714b725ae77Skettenis     case bfd_mach_sh4_nofpu:
2715b725ae77Skettenis     case bfd_mach_sh4a_nofpu:
2716b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh4_nofpu_register_name);
2717b725ae77Skettenis       break;
2718b725ae77Skettenis 
2719b725ae77Skettenis     case bfd_mach_sh4al_dsp:
2720b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh4al_dsp_register_name);
2721b725ae77Skettenis       set_gdbarch_register_sim_regno (gdbarch, sh_dsp_register_sim_regno);
2722b725ae77Skettenis       break;
2723b725ae77Skettenis 
2724b725ae77Skettenis     default:
2725b725ae77Skettenis       set_gdbarch_register_name (gdbarch, sh_sh_register_name);
2726b725ae77Skettenis       break;
2727b725ae77Skettenis     }
2728b725ae77Skettenis 
2729b725ae77Skettenis   /* Hook in ABI-specific overrides, if they have been registered.  */
2730b725ae77Skettenis   gdbarch_init_osabi (info, gdbarch);
2731b725ae77Skettenis 
2732b725ae77Skettenis   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
2733b725ae77Skettenis   frame_unwind_append_sniffer (gdbarch, sh_frame_sniffer);
2734b725ae77Skettenis 
2735b725ae77Skettenis   return gdbarch;
2736b725ae77Skettenis }
2737b725ae77Skettenis 
2738b725ae77Skettenis extern initialize_file_ftype _initialize_sh_tdep;	/* -Wmissing-prototypes */
2739b725ae77Skettenis 
2740e93f7393Sniklas void
_initialize_sh_tdep(void)2741b725ae77Skettenis _initialize_sh_tdep (void)
2742e93f7393Sniklas {
2743e93f7393Sniklas   struct cmd_list_element *c;
2744e93f7393Sniklas 
2745b725ae77Skettenis   gdbarch_register (bfd_arch_sh, sh_gdbarch_init, NULL);
2746e93f7393Sniklas 
2747b725ae77Skettenis   add_com ("regs", class_vars, sh_show_regs_command, "Print all registers");
2748e93f7393Sniklas }
2749