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