1b725ae77Skettenis /* Target-dependent code for Renesas Super-H, for GDB.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4b725ae77Skettenis 2002, 2003, 2004 Free Software Foundation, Inc.
5b725ae77Skettenis
6b725ae77Skettenis This file is part of GDB.
7b725ae77Skettenis
8b725ae77Skettenis This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis it under the terms of the GNU General Public License as published by
10b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis (at your option) any later version.
12b725ae77Skettenis
13b725ae77Skettenis This program is distributed in the hope that it will be useful,
14b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16b725ae77Skettenis GNU General Public License for more details.
17b725ae77Skettenis
18b725ae77Skettenis You should have received a copy of the GNU General Public License
19b725ae77Skettenis along with this program; if not, write to the Free Software
20b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis Boston, MA 02111-1307, USA. */
22b725ae77Skettenis
23b725ae77Skettenis /*
24b725ae77Skettenis Contributed by Steve Chamberlain
25b725ae77Skettenis sac@cygnus.com
26b725ae77Skettenis */
27b725ae77Skettenis
28b725ae77Skettenis #include "defs.h"
29b725ae77Skettenis #include "frame.h"
30b725ae77Skettenis #include "symtab.h"
31b725ae77Skettenis #include "objfiles.h"
32b725ae77Skettenis #include "gdbtypes.h"
33b725ae77Skettenis #include "gdbcmd.h"
34b725ae77Skettenis #include "gdbcore.h"
35b725ae77Skettenis #include "value.h"
36b725ae77Skettenis #include "dis-asm.h"
37b725ae77Skettenis #include "inferior.h"
38b725ae77Skettenis #include "gdb_string.h"
39b725ae77Skettenis #include "arch-utils.h"
40b725ae77Skettenis #include "floatformat.h"
41b725ae77Skettenis #include "regcache.h"
42b725ae77Skettenis #include "doublest.h"
43b725ae77Skettenis #include "osabi.h"
44b725ae77Skettenis
45b725ae77Skettenis #include "elf-bfd.h"
46b725ae77Skettenis #include "solib-svr4.h"
47b725ae77Skettenis
48b725ae77Skettenis /* sh flags */
49b725ae77Skettenis #include "elf/sh.h"
50b725ae77Skettenis /* registers numbers shared with the simulator */
51b725ae77Skettenis #include "gdb/sim-sh.h"
52b725ae77Skettenis
53b725ae77Skettenis /* Information that is dependent on the processor variant. */
54b725ae77Skettenis enum sh_abi
55b725ae77Skettenis {
56b725ae77Skettenis SH_ABI_UNKNOWN,
57b725ae77Skettenis SH_ABI_32,
58b725ae77Skettenis SH_ABI_64
59b725ae77Skettenis };
60b725ae77Skettenis
61b725ae77Skettenis struct gdbarch_tdep
62b725ae77Skettenis {
63b725ae77Skettenis enum sh_abi sh_abi;
64b725ae77Skettenis };
65b725ae77Skettenis
66b725ae77Skettenis /* Registers of SH5 */
67b725ae77Skettenis enum
68b725ae77Skettenis {
69b725ae77Skettenis R0_REGNUM = 0,
70b725ae77Skettenis DEFAULT_RETURN_REGNUM = 2,
71b725ae77Skettenis STRUCT_RETURN_REGNUM = 2,
72b725ae77Skettenis ARG0_REGNUM = 2,
73b725ae77Skettenis ARGLAST_REGNUM = 9,
74b725ae77Skettenis FLOAT_ARGLAST_REGNUM = 11,
75b725ae77Skettenis PR_REGNUM = 18,
76b725ae77Skettenis SR_REGNUM = 65,
77b725ae77Skettenis DR0_REGNUM = 141,
78b725ae77Skettenis DR_LAST_REGNUM = 172,
79b725ae77Skettenis /* FPP stands for Floating Point Pair, to avoid confusion with
80b725ae77Skettenis GDB's FP0_REGNUM, which is the number of the first Floating
81b725ae77Skettenis point register. Unfortunately on the sh5, the floating point
82b725ae77Skettenis registers are called FR, and the floating point pairs are called FP. */
83b725ae77Skettenis FPP0_REGNUM = 173,
84b725ae77Skettenis FPP_LAST_REGNUM = 204,
85b725ae77Skettenis FV0_REGNUM = 205,
86b725ae77Skettenis FV_LAST_REGNUM = 220,
87b725ae77Skettenis R0_C_REGNUM = 221,
88b725ae77Skettenis R_LAST_C_REGNUM = 236,
89b725ae77Skettenis PC_C_REGNUM = 237,
90b725ae77Skettenis GBR_C_REGNUM = 238,
91b725ae77Skettenis MACH_C_REGNUM = 239,
92b725ae77Skettenis MACL_C_REGNUM = 240,
93b725ae77Skettenis PR_C_REGNUM = 241,
94b725ae77Skettenis T_C_REGNUM = 242,
95b725ae77Skettenis FPSCR_C_REGNUM = 243,
96b725ae77Skettenis FPUL_C_REGNUM = 244,
97b725ae77Skettenis FP0_C_REGNUM = 245,
98b725ae77Skettenis FP_LAST_C_REGNUM = 260,
99b725ae77Skettenis DR0_C_REGNUM = 261,
100b725ae77Skettenis DR_LAST_C_REGNUM = 268,
101b725ae77Skettenis FV0_C_REGNUM = 269,
102b725ae77Skettenis FV_LAST_C_REGNUM = 272,
103b725ae77Skettenis FPSCR_REGNUM = SIM_SH64_FPCSR_REGNUM,
104b725ae77Skettenis SSR_REGNUM = SIM_SH64_SSR_REGNUM,
105b725ae77Skettenis SPC_REGNUM = SIM_SH64_SPC_REGNUM,
106b725ae77Skettenis TR7_REGNUM = SIM_SH64_TR0_REGNUM + 7,
107b725ae77Skettenis FP_LAST_REGNUM = SIM_SH64_FR0_REGNUM + SIM_SH64_NR_FP_REGS - 1
108b725ae77Skettenis };
109b725ae77Skettenis
110b725ae77Skettenis
111b725ae77Skettenis /* Define other aspects of the stack frame.
112b725ae77Skettenis we keep a copy of the worked out return pc lying around, since it
113b725ae77Skettenis is a useful bit of info */
114b725ae77Skettenis
115b725ae77Skettenis struct frame_extra_info
116b725ae77Skettenis {
117b725ae77Skettenis CORE_ADDR return_pc;
118b725ae77Skettenis int leaf_function;
119b725ae77Skettenis int f_offset;
120b725ae77Skettenis };
121b725ae77Skettenis
122b725ae77Skettenis static const char *
sh64_register_name(int reg_nr)123b725ae77Skettenis sh64_register_name (int reg_nr)
124b725ae77Skettenis {
125b725ae77Skettenis static char *register_names[] =
126b725ae77Skettenis {
127b725ae77Skettenis /* SH MEDIA MODE (ISA 32) */
128b725ae77Skettenis /* general registers (64-bit) 0-63 */
129b725ae77Skettenis "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
130b725ae77Skettenis "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
131b725ae77Skettenis "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
132b725ae77Skettenis "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
133b725ae77Skettenis "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
134b725ae77Skettenis "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
135b725ae77Skettenis "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
136b725ae77Skettenis "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
137b725ae77Skettenis
138b725ae77Skettenis /* pc (64-bit) 64 */
139b725ae77Skettenis "pc",
140b725ae77Skettenis
141b725ae77Skettenis /* status reg., saved status reg., saved pc reg. (64-bit) 65-67 */
142b725ae77Skettenis "sr", "ssr", "spc",
143b725ae77Skettenis
144b725ae77Skettenis /* target registers (64-bit) 68-75*/
145b725ae77Skettenis "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7",
146b725ae77Skettenis
147b725ae77Skettenis /* floating point state control register (32-bit) 76 */
148b725ae77Skettenis "fpscr",
149b725ae77Skettenis
150b725ae77Skettenis /* single precision floating point registers (32-bit) 77-140*/
151b725ae77Skettenis "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7",
152b725ae77Skettenis "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
153b725ae77Skettenis "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
154b725ae77Skettenis "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31",
155b725ae77Skettenis "fr32", "fr33", "fr34", "fr35", "fr36", "fr37", "fr38", "fr39",
156b725ae77Skettenis "fr40", "fr41", "fr42", "fr43", "fr44", "fr45", "fr46", "fr47",
157b725ae77Skettenis "fr48", "fr49", "fr50", "fr51", "fr52", "fr53", "fr54", "fr55",
158b725ae77Skettenis "fr56", "fr57", "fr58", "fr59", "fr60", "fr61", "fr62", "fr63",
159b725ae77Skettenis
160b725ae77Skettenis /* double precision registers (pseudo) 141-172 */
161b725ae77Skettenis "dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
162b725ae77Skettenis "dr16", "dr18", "dr20", "dr22", "dr24", "dr26", "dr28", "dr30",
163b725ae77Skettenis "dr32", "dr34", "dr36", "dr38", "dr40", "dr42", "dr44", "dr46",
164b725ae77Skettenis "dr48", "dr50", "dr52", "dr54", "dr56", "dr58", "dr60", "dr62",
165b725ae77Skettenis
166b725ae77Skettenis /* floating point pairs (pseudo) 173-204*/
167b725ae77Skettenis "fp0", "fp2", "fp4", "fp6", "fp8", "fp10", "fp12", "fp14",
168b725ae77Skettenis "fp16", "fp18", "fp20", "fp22", "fp24", "fp26", "fp28", "fp30",
169b725ae77Skettenis "fp32", "fp34", "fp36", "fp38", "fp40", "fp42", "fp44", "fp46",
170b725ae77Skettenis "fp48", "fp50", "fp52", "fp54", "fp56", "fp58", "fp60", "fp62",
171b725ae77Skettenis
172b725ae77Skettenis /* floating point vectors (4 floating point regs) (pseudo) 205-220*/
173b725ae77Skettenis "fv0", "fv4", "fv8", "fv12", "fv16", "fv20", "fv24", "fv28",
174b725ae77Skettenis "fv32", "fv36", "fv40", "fv44", "fv48", "fv52", "fv56", "fv60",
175b725ae77Skettenis
176b725ae77Skettenis /* SH COMPACT MODE (ISA 16) (all pseudo) 221-272*/
177b725ae77Skettenis "r0_c", "r1_c", "r2_c", "r3_c", "r4_c", "r5_c", "r6_c", "r7_c",
178b725ae77Skettenis "r8_c", "r9_c", "r10_c", "r11_c", "r12_c", "r13_c", "r14_c", "r15_c",
179b725ae77Skettenis "pc_c",
180b725ae77Skettenis "gbr_c", "mach_c", "macl_c", "pr_c", "t_c",
181b725ae77Skettenis "fpscr_c", "fpul_c",
182b725ae77Skettenis "fr0_c", "fr1_c", "fr2_c", "fr3_c", "fr4_c", "fr5_c", "fr6_c", "fr7_c",
183b725ae77Skettenis "fr8_c", "fr9_c", "fr10_c", "fr11_c", "fr12_c", "fr13_c", "fr14_c", "fr15_c",
184b725ae77Skettenis "dr0_c", "dr2_c", "dr4_c", "dr6_c", "dr8_c", "dr10_c", "dr12_c", "dr14_c",
185b725ae77Skettenis "fv0_c", "fv4_c", "fv8_c", "fv12_c",
186b725ae77Skettenis /* FIXME!!!! XF0 XF15, XD0 XD14 ?????*/
187b725ae77Skettenis };
188b725ae77Skettenis
189b725ae77Skettenis if (reg_nr < 0)
190b725ae77Skettenis return NULL;
191b725ae77Skettenis if (reg_nr >= (sizeof (register_names) / sizeof (*register_names)))
192b725ae77Skettenis return NULL;
193b725ae77Skettenis return register_names[reg_nr];
194b725ae77Skettenis }
195b725ae77Skettenis
196b725ae77Skettenis #define NUM_PSEUDO_REGS_SH_MEDIA 80
197b725ae77Skettenis #define NUM_PSEUDO_REGS_SH_COMPACT 51
198b725ae77Skettenis
199b725ae77Skettenis /* Macros and functions for setting and testing a bit in a minimal
200b725ae77Skettenis symbol that marks it as 32-bit function. The MSB of the minimal
201b725ae77Skettenis symbol's "info" field is used for this purpose.
202b725ae77Skettenis
203b725ae77Skettenis ELF_MAKE_MSYMBOL_SPECIAL
204b725ae77Skettenis tests whether an ELF symbol is "special", i.e. refers
205b725ae77Skettenis to a 32-bit function, and sets a "special" bit in a
206b725ae77Skettenis minimal symbol to mark it as a 32-bit function
207b725ae77Skettenis MSYMBOL_IS_SPECIAL tests the "special" bit in a minimal symbol */
208b725ae77Skettenis
209b725ae77Skettenis #define MSYMBOL_IS_SPECIAL(msym) \
210b725ae77Skettenis (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
211b725ae77Skettenis
212b725ae77Skettenis static void
sh64_elf_make_msymbol_special(asymbol * sym,struct minimal_symbol * msym)213b725ae77Skettenis sh64_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
214b725ae77Skettenis {
215b725ae77Skettenis if (msym == NULL)
216b725ae77Skettenis return;
217b725ae77Skettenis
218b725ae77Skettenis if (((elf_symbol_type *)(sym))->internal_elf_sym.st_other == STO_SH5_ISA32)
219b725ae77Skettenis {
220b725ae77Skettenis MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym)) | 0x80000000);
221b725ae77Skettenis SYMBOL_VALUE_ADDRESS (msym) |= 1;
222b725ae77Skettenis }
223b725ae77Skettenis }
224b725ae77Skettenis
225b725ae77Skettenis /* ISA32 (shmedia) function addresses are odd (bit 0 is set). Here
226b725ae77Skettenis are some macros to test, set, or clear bit 0 of addresses. */
227b725ae77Skettenis #define IS_ISA32_ADDR(addr) ((addr) & 1)
228b725ae77Skettenis #define MAKE_ISA32_ADDR(addr) ((addr) | 1)
229b725ae77Skettenis #define UNMAKE_ISA32_ADDR(addr) ((addr) & ~1)
230b725ae77Skettenis
231b725ae77Skettenis static int
pc_is_isa32(bfd_vma memaddr)232b725ae77Skettenis pc_is_isa32 (bfd_vma memaddr)
233b725ae77Skettenis {
234b725ae77Skettenis struct minimal_symbol *sym;
235b725ae77Skettenis
236b725ae77Skettenis /* If bit 0 of the address is set, assume this is a
237b725ae77Skettenis ISA32 (shmedia) address. */
238b725ae77Skettenis if (IS_ISA32_ADDR (memaddr))
239b725ae77Skettenis return 1;
240b725ae77Skettenis
241b725ae77Skettenis /* A flag indicating that this is a ISA32 function is stored by elfread.c in
242b725ae77Skettenis the high bit of the info field. Use this to decide if the function is
243b725ae77Skettenis ISA16 or ISA32. */
244b725ae77Skettenis sym = lookup_minimal_symbol_by_pc (memaddr);
245b725ae77Skettenis if (sym)
246b725ae77Skettenis return MSYMBOL_IS_SPECIAL (sym);
247b725ae77Skettenis else
248b725ae77Skettenis return 0;
249b725ae77Skettenis }
250b725ae77Skettenis
251b725ae77Skettenis static const unsigned char *
sh64_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)252b725ae77Skettenis sh64_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
253b725ae77Skettenis {
254b725ae77Skettenis /* The BRK instruction for shmedia is
255b725ae77Skettenis 01101111 11110101 11111111 11110000
256b725ae77Skettenis which translates in big endian mode to 0x6f, 0xf5, 0xff, 0xf0
257b725ae77Skettenis and in little endian mode to 0xf0, 0xff, 0xf5, 0x6f */
258b725ae77Skettenis
259b725ae77Skettenis /* The BRK instruction for shcompact is
260b725ae77Skettenis 00000000 00111011
261b725ae77Skettenis which translates in big endian mode to 0x0, 0x3b
262b725ae77Skettenis and in little endian mode to 0x3b, 0x0*/
263b725ae77Skettenis
264b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
265b725ae77Skettenis {
266b725ae77Skettenis if (pc_is_isa32 (*pcptr))
267b725ae77Skettenis {
268b725ae77Skettenis static unsigned char big_breakpoint_media[] = {0x6f, 0xf5, 0xff, 0xf0};
269b725ae77Skettenis *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
270b725ae77Skettenis *lenptr = sizeof (big_breakpoint_media);
271b725ae77Skettenis return big_breakpoint_media;
272b725ae77Skettenis }
273b725ae77Skettenis else
274b725ae77Skettenis {
275b725ae77Skettenis static unsigned char big_breakpoint_compact[] = {0x0, 0x3b};
276b725ae77Skettenis *lenptr = sizeof (big_breakpoint_compact);
277b725ae77Skettenis return big_breakpoint_compact;
278b725ae77Skettenis }
279b725ae77Skettenis }
280b725ae77Skettenis else
281b725ae77Skettenis {
282b725ae77Skettenis if (pc_is_isa32 (*pcptr))
283b725ae77Skettenis {
284b725ae77Skettenis static unsigned char little_breakpoint_media[] = {0xf0, 0xff, 0xf5, 0x6f};
285b725ae77Skettenis *pcptr = UNMAKE_ISA32_ADDR (*pcptr);
286b725ae77Skettenis *lenptr = sizeof (little_breakpoint_media);
287b725ae77Skettenis return little_breakpoint_media;
288b725ae77Skettenis }
289b725ae77Skettenis else
290b725ae77Skettenis {
291b725ae77Skettenis static unsigned char little_breakpoint_compact[] = {0x3b, 0x0};
292b725ae77Skettenis *lenptr = sizeof (little_breakpoint_compact);
293b725ae77Skettenis return little_breakpoint_compact;
294b725ae77Skettenis }
295b725ae77Skettenis }
296b725ae77Skettenis }
297b725ae77Skettenis
298b725ae77Skettenis /* Prologue looks like
299b725ae77Skettenis [mov.l <regs>,@-r15]...
300b725ae77Skettenis [sts.l pr,@-r15]
301b725ae77Skettenis [mov.l r14,@-r15]
302b725ae77Skettenis [mov r15,r14]
303b725ae77Skettenis
304b725ae77Skettenis Actually it can be more complicated than this. For instance, with
305b725ae77Skettenis newer gcc's:
306b725ae77Skettenis
307b725ae77Skettenis mov.l r14,@-r15
308b725ae77Skettenis add #-12,r15
309b725ae77Skettenis mov r15,r14
310b725ae77Skettenis mov r4,r1
311b725ae77Skettenis mov r5,r2
312b725ae77Skettenis mov.l r6,@(4,r14)
313b725ae77Skettenis mov.l r7,@(8,r14)
314b725ae77Skettenis mov.b r1,@r14
315b725ae77Skettenis mov r14,r1
316b725ae77Skettenis mov r14,r1
317b725ae77Skettenis add #2,r1
318b725ae77Skettenis mov.w r2,@r1
319b725ae77Skettenis
320b725ae77Skettenis */
321b725ae77Skettenis
322b725ae77Skettenis /* PTABS/L Rn, TRa 0110101111110001nnnnnnl00aaa0000
323b725ae77Skettenis with l=1 and n = 18 0110101111110001010010100aaa0000 */
324b725ae77Skettenis #define IS_PTABSL_R18(x) (((x) & 0xffffff8f) == 0x6bf14a00)
325b725ae77Skettenis
326b725ae77Skettenis /* STS.L PR,@-r0 0100000000100010
327b725ae77Skettenis r0-4-->r0, PR-->(r0) */
328b725ae77Skettenis #define IS_STS_R0(x) ((x) == 0x4022)
329b725ae77Skettenis
330b725ae77Skettenis /* STS PR, Rm 0000mmmm00101010
331b725ae77Skettenis PR-->Rm */
332b725ae77Skettenis #define IS_STS_PR(x) (((x) & 0xf0ff) == 0x2a)
333b725ae77Skettenis
334b725ae77Skettenis /* MOV.L Rm,@(disp,r15) 00011111mmmmdddd
335b725ae77Skettenis Rm-->(dispx4+r15) */
336b725ae77Skettenis #define IS_MOV_TO_R15(x) (((x) & 0xff00) == 0x1f00)
337b725ae77Skettenis
338b725ae77Skettenis /* MOV.L R14,@(disp,r15) 000111111110dddd
339b725ae77Skettenis R14-->(dispx4+r15) */
340b725ae77Skettenis #define IS_MOV_R14(x) (((x) & 0xfff0) == 0x1fe0)
341b725ae77Skettenis
342b725ae77Skettenis /* ST.Q R14, disp, R18 101011001110dddddddddd0100100000
343b725ae77Skettenis R18-->(dispx8+R14) */
344b725ae77Skettenis #define IS_STQ_R18_R14(x) (((x) & 0xfff003ff) == 0xace00120)
345b725ae77Skettenis
346b725ae77Skettenis /* ST.Q R15, disp, R18 101011001111dddddddddd0100100000
347b725ae77Skettenis R18-->(dispx8+R15) */
348b725ae77Skettenis #define IS_STQ_R18_R15(x) (((x) & 0xfff003ff) == 0xacf00120)
349b725ae77Skettenis
350b725ae77Skettenis /* ST.L R15, disp, R18 101010001111dddddddddd0100100000
351b725ae77Skettenis R18-->(dispx4+R15) */
352b725ae77Skettenis #define IS_STL_R18_R15(x) (((x) & 0xfff003ff) == 0xa8f00120)
353b725ae77Skettenis
354b725ae77Skettenis /* ST.Q R15, disp, R14 1010 1100 1111 dddd dddd dd00 1110 0000
355b725ae77Skettenis R14-->(dispx8+R15) */
356b725ae77Skettenis #define IS_STQ_R14_R15(x) (((x) & 0xfff003ff) == 0xacf000e0)
357b725ae77Skettenis
358b725ae77Skettenis /* ST.L R15, disp, R14 1010 1000 1111 dddd dddd dd00 1110 0000
359b725ae77Skettenis R14-->(dispx4+R15) */
360b725ae77Skettenis #define IS_STL_R14_R15(x) (((x) & 0xfff003ff) == 0xa8f000e0)
361b725ae77Skettenis
362b725ae77Skettenis /* ADDI.L R15,imm,R15 1101 0100 1111 ssss ssss ss00 1111 0000
363b725ae77Skettenis R15 + imm --> R15 */
364b725ae77Skettenis #define IS_ADDIL_SP_MEDIA(x) (((x) & 0xfff003ff) == 0xd4f000f0)
365b725ae77Skettenis
366b725ae77Skettenis /* ADDI R15,imm,R15 1101 0000 1111 ssss ssss ss00 1111 0000
367b725ae77Skettenis R15 + imm --> R15 */
368b725ae77Skettenis #define IS_ADDI_SP_MEDIA(x) (((x) & 0xfff003ff) == 0xd0f000f0)
369b725ae77Skettenis
370b725ae77Skettenis /* ADD.L R15,R63,R14 0000 0000 1111 1000 1111 1100 1110 0000
371b725ae77Skettenis R15 + R63 --> R14 */
372b725ae77Skettenis #define IS_ADDL_SP_FP_MEDIA(x) ((x) == 0x00f8fce0)
373b725ae77Skettenis
374b725ae77Skettenis /* ADD R15,R63,R14 0000 0000 1111 1001 1111 1100 1110 0000
375b725ae77Skettenis R15 + R63 --> R14 */
376b725ae77Skettenis #define IS_ADD_SP_FP_MEDIA(x) ((x) == 0x00f9fce0)
377b725ae77Skettenis
378b725ae77Skettenis #define IS_MOV_SP_FP_MEDIA(x) (IS_ADDL_SP_FP_MEDIA(x) || IS_ADD_SP_FP_MEDIA(x))
379b725ae77Skettenis
380b725ae77Skettenis /* MOV #imm, R0 1110 0000 ssss ssss
381b725ae77Skettenis #imm-->R0 */
382b725ae77Skettenis #define IS_MOV_R0(x) (((x) & 0xff00) == 0xe000)
383b725ae77Skettenis
384b725ae77Skettenis /* MOV.L @(disp,PC), R0 1101 0000 iiii iiii */
385b725ae77Skettenis #define IS_MOVL_R0(x) (((x) & 0xff00) == 0xd000)
386b725ae77Skettenis
387b725ae77Skettenis /* ADD r15,r0 0011 0000 1111 1100
388b725ae77Skettenis r15+r0-->r0 */
389b725ae77Skettenis #define IS_ADD_SP_R0(x) ((x) == 0x30fc)
390b725ae77Skettenis
391b725ae77Skettenis /* MOV.L R14 @-R0 0010 0000 1110 0110
392b725ae77Skettenis R14-->(R0-4), R0-4-->R0 */
393b725ae77Skettenis #define IS_MOV_R14_R0(x) ((x) == 0x20e6)
394b725ae77Skettenis
395b725ae77Skettenis /* ADD Rm,R63,Rn Rm+R63-->Rn 0000 00mm mmmm 1001 1111 11nn nnnn 0000
396b725ae77Skettenis where Rm is one of r2-r9 which are the argument registers. */
397b725ae77Skettenis /* FIXME: Recognize the float and double register moves too! */
398b725ae77Skettenis #define IS_MEDIA_IND_ARG_MOV(x) \
399b725ae77Skettenis ((((x) & 0xfc0ffc0f) == 0x0009fc00) && (((x) & 0x03f00000) >= 0x00200000 && ((x) & 0x03f00000) <= 0x00900000))
400b725ae77Skettenis
401b725ae77Skettenis /* ST.Q Rn,0,Rm Rm-->Rn+0 1010 11nn nnnn 0000 0000 00mm mmmm 0000
402b725ae77Skettenis or ST.L Rn,0,Rm Rm-->Rn+0 1010 10nn nnnn 0000 0000 00mm mmmm 0000
403b725ae77Skettenis where Rm is one of r2-r9 which are the argument registers. */
404b725ae77Skettenis #define IS_MEDIA_ARG_MOV(x) \
405b725ae77Skettenis (((((x) & 0xfc0ffc0f) == 0xac000000) || (((x) & 0xfc0ffc0f) == 0xa8000000)) \
406b725ae77Skettenis && (((x) & 0x000003f0) >= 0x00000020 && ((x) & 0x000003f0) <= 0x00000090))
407b725ae77Skettenis
408b725ae77Skettenis /* ST.B R14,0,Rn Rn-->(R14+0) 1010 0000 1110 0000 0000 00nn nnnn 0000*/
409b725ae77Skettenis /* ST.W R14,0,Rn Rn-->(R14+0) 1010 0100 1110 0000 0000 00nn nnnn 0000*/
410b725ae77Skettenis /* ST.L R14,0,Rn Rn-->(R14+0) 1010 1000 1110 0000 0000 00nn nnnn 0000*/
411b725ae77Skettenis /* FST.S R14,0,FRn Rn-->(R14+0) 1011 0100 1110 0000 0000 00nn nnnn 0000*/
412b725ae77Skettenis /* FST.D R14,0,DRn Rn-->(R14+0) 1011 1100 1110 0000 0000 00nn nnnn 0000*/
413b725ae77Skettenis #define IS_MEDIA_MOV_TO_R14(x) \
414b725ae77Skettenis ((((x) & 0xfffffc0f) == 0xa0e00000) \
415b725ae77Skettenis || (((x) & 0xfffffc0f) == 0xa4e00000) \
416b725ae77Skettenis || (((x) & 0xfffffc0f) == 0xa8e00000) \
417b725ae77Skettenis || (((x) & 0xfffffc0f) == 0xb4e00000) \
418b725ae77Skettenis || (((x) & 0xfffffc0f) == 0xbce00000))
419b725ae77Skettenis
420b725ae77Skettenis /* MOV Rm, Rn Rm-->Rn 0110 nnnn mmmm 0011
421b725ae77Skettenis where Rm is r2-r9 */
422b725ae77Skettenis #define IS_COMPACT_IND_ARG_MOV(x) \
423b725ae77Skettenis ((((x) & 0xf00f) == 0x6003) && (((x) & 0x00f0) >= 0x0020) && (((x) & 0x00f0) <= 0x0090))
424b725ae77Skettenis
425b725ae77Skettenis /* compact direct arg move!
426b725ae77Skettenis MOV.L Rn, @r14 0010 1110 mmmm 0010 */
427b725ae77Skettenis #define IS_COMPACT_ARG_MOV(x) \
428b725ae77Skettenis (((((x) & 0xff0f) == 0x2e02) && (((x) & 0x00f0) >= 0x0020) && ((x) & 0x00f0) <= 0x0090))
429b725ae77Skettenis
430b725ae77Skettenis /* MOV.B Rm, @R14 0010 1110 mmmm 0000
431b725ae77Skettenis MOV.W Rm, @R14 0010 1110 mmmm 0001 */
432b725ae77Skettenis #define IS_COMPACT_MOV_TO_R14(x) \
433b725ae77Skettenis ((((x) & 0xff0f) == 0x2e00) || (((x) & 0xff0f) == 0x2e01))
434b725ae77Skettenis
435b725ae77Skettenis #define IS_JSR_R0(x) ((x) == 0x400b)
436b725ae77Skettenis #define IS_NOP(x) ((x) == 0x0009)
437b725ae77Skettenis
438b725ae77Skettenis
439b725ae77Skettenis /* MOV r15,r14 0110111011110011
440b725ae77Skettenis r15-->r14 */
441b725ae77Skettenis #define IS_MOV_SP_FP(x) ((x) == 0x6ef3)
442b725ae77Skettenis
443b725ae77Skettenis /* ADD #imm,r15 01111111iiiiiiii
444b725ae77Skettenis r15+imm-->r15 */
445b725ae77Skettenis #define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
446b725ae77Skettenis
447b725ae77Skettenis /* Skip any prologue before the guts of a function */
448b725ae77Skettenis
449b725ae77Skettenis /* Skip the prologue using the debug information. If this fails we'll
450b725ae77Skettenis fall back on the 'guess' method below. */
451b725ae77Skettenis static CORE_ADDR
after_prologue(CORE_ADDR pc)452b725ae77Skettenis after_prologue (CORE_ADDR pc)
453b725ae77Skettenis {
454b725ae77Skettenis struct symtab_and_line sal;
455b725ae77Skettenis CORE_ADDR func_addr, func_end;
456b725ae77Skettenis
457b725ae77Skettenis /* If we can not find the symbol in the partial symbol table, then
458b725ae77Skettenis there is no hope we can determine the function's start address
459b725ae77Skettenis with this code. */
460b725ae77Skettenis if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
461b725ae77Skettenis return 0;
462b725ae77Skettenis
463b725ae77Skettenis /* Get the line associated with FUNC_ADDR. */
464b725ae77Skettenis sal = find_pc_line (func_addr, 0);
465b725ae77Skettenis
466b725ae77Skettenis /* There are only two cases to consider. First, the end of the source line
467b725ae77Skettenis is within the function bounds. In that case we return the end of the
468b725ae77Skettenis source line. Second is the end of the source line extends beyond the
469b725ae77Skettenis bounds of the current function. We need to use the slow code to
470b725ae77Skettenis examine instructions in that case. */
471b725ae77Skettenis if (sal.end < func_end)
472b725ae77Skettenis return sal.end;
473b725ae77Skettenis else
474b725ae77Skettenis return 0;
475b725ae77Skettenis }
476b725ae77Skettenis
477b725ae77Skettenis static CORE_ADDR
look_for_args_moves(CORE_ADDR start_pc,int media_mode)478b725ae77Skettenis look_for_args_moves (CORE_ADDR start_pc, int media_mode)
479b725ae77Skettenis {
480b725ae77Skettenis CORE_ADDR here, end;
481b725ae77Skettenis int w;
482b725ae77Skettenis int insn_size = (media_mode ? 4 : 2);
483b725ae77Skettenis
484b725ae77Skettenis for (here = start_pc, end = start_pc + (insn_size * 28); here < end;)
485b725ae77Skettenis {
486b725ae77Skettenis if (media_mode)
487b725ae77Skettenis {
488b725ae77Skettenis w = read_memory_integer (UNMAKE_ISA32_ADDR (here), insn_size);
489b725ae77Skettenis here += insn_size;
490b725ae77Skettenis if (IS_MEDIA_IND_ARG_MOV (w))
491b725ae77Skettenis {
492b725ae77Skettenis /* This must be followed by a store to r14, so the argument
493b725ae77Skettenis is where the debug info says it is. This can happen after
494b725ae77Skettenis the SP has been saved, unfortunately. */
495b725ae77Skettenis
496b725ae77Skettenis int next_insn = read_memory_integer (UNMAKE_ISA32_ADDR (here),
497b725ae77Skettenis insn_size);
498b725ae77Skettenis here += insn_size;
499b725ae77Skettenis if (IS_MEDIA_MOV_TO_R14 (next_insn))
500b725ae77Skettenis start_pc = here;
501b725ae77Skettenis }
502b725ae77Skettenis else if (IS_MEDIA_ARG_MOV (w))
503b725ae77Skettenis {
504b725ae77Skettenis /* These instructions store directly the argument in r14. */
505b725ae77Skettenis start_pc = here;
506b725ae77Skettenis }
507b725ae77Skettenis else
508b725ae77Skettenis break;
509b725ae77Skettenis }
510b725ae77Skettenis else
511b725ae77Skettenis {
512b725ae77Skettenis w = read_memory_integer (here, insn_size);
513b725ae77Skettenis w = w & 0xffff;
514b725ae77Skettenis here += insn_size;
515b725ae77Skettenis if (IS_COMPACT_IND_ARG_MOV (w))
516b725ae77Skettenis {
517b725ae77Skettenis /* This must be followed by a store to r14, so the argument
518b725ae77Skettenis is where the debug info says it is. This can happen after
519b725ae77Skettenis the SP has been saved, unfortunately. */
520b725ae77Skettenis
521b725ae77Skettenis int next_insn = 0xffff & read_memory_integer (here, insn_size);
522b725ae77Skettenis here += insn_size;
523b725ae77Skettenis if (IS_COMPACT_MOV_TO_R14 (next_insn))
524b725ae77Skettenis start_pc = here;
525b725ae77Skettenis }
526b725ae77Skettenis else if (IS_COMPACT_ARG_MOV (w))
527b725ae77Skettenis {
528b725ae77Skettenis /* These instructions store directly the argument in r14. */
529b725ae77Skettenis start_pc = here;
530b725ae77Skettenis }
531b725ae77Skettenis else if (IS_MOVL_R0 (w))
532b725ae77Skettenis {
533b725ae77Skettenis /* There is a function that gcc calls to get the arguments
534b725ae77Skettenis passed correctly to the function. Only after this
535b725ae77Skettenis function call the arguments will be found at the place
536b725ae77Skettenis where they are supposed to be. This happens in case the
537b725ae77Skettenis argument has to be stored into a 64-bit register (for
538b725ae77Skettenis instance doubles, long longs). SHcompact doesn't have
539b725ae77Skettenis access to the full 64-bits, so we store the register in
540b725ae77Skettenis stack slot and store the address of the stack slot in
541b725ae77Skettenis the register, then do a call through a wrapper that
542b725ae77Skettenis loads the memory value into the register. A SHcompact
543b725ae77Skettenis callee calls an argument decoder
544b725ae77Skettenis (GCC_shcompact_incoming_args) that stores the 64-bit
545b725ae77Skettenis value in a stack slot and stores the address of the
546b725ae77Skettenis stack slot in the register. GCC thinks the argument is
547b725ae77Skettenis just passed by transparent reference, but this is only
548b725ae77Skettenis true after the argument decoder is called. Such a call
549b725ae77Skettenis needs to be considered part of the prologue. */
550b725ae77Skettenis
551b725ae77Skettenis /* This must be followed by a JSR @r0 instruction and by
552b725ae77Skettenis a NOP instruction. After these, the prologue is over! */
553b725ae77Skettenis
554b725ae77Skettenis int next_insn = 0xffff & read_memory_integer (here, insn_size);
555b725ae77Skettenis here += insn_size;
556b725ae77Skettenis if (IS_JSR_R0 (next_insn))
557b725ae77Skettenis {
558b725ae77Skettenis next_insn = 0xffff & read_memory_integer (here, insn_size);
559b725ae77Skettenis here += insn_size;
560b725ae77Skettenis
561b725ae77Skettenis if (IS_NOP (next_insn))
562b725ae77Skettenis start_pc = here;
563b725ae77Skettenis }
564b725ae77Skettenis }
565b725ae77Skettenis else
566b725ae77Skettenis break;
567b725ae77Skettenis }
568b725ae77Skettenis }
569b725ae77Skettenis
570b725ae77Skettenis return start_pc;
571b725ae77Skettenis }
572b725ae77Skettenis
573b725ae77Skettenis static CORE_ADDR
sh64_skip_prologue_hard_way(CORE_ADDR start_pc)574b725ae77Skettenis sh64_skip_prologue_hard_way (CORE_ADDR start_pc)
575b725ae77Skettenis {
576b725ae77Skettenis CORE_ADDR here, end;
577b725ae77Skettenis int updated_fp = 0;
578b725ae77Skettenis int insn_size = 4;
579b725ae77Skettenis int media_mode = 1;
580b725ae77Skettenis
581b725ae77Skettenis if (!start_pc)
582b725ae77Skettenis return 0;
583b725ae77Skettenis
584b725ae77Skettenis if (pc_is_isa32 (start_pc) == 0)
585b725ae77Skettenis {
586b725ae77Skettenis insn_size = 2;
587b725ae77Skettenis media_mode = 0;
588b725ae77Skettenis }
589b725ae77Skettenis
590b725ae77Skettenis for (here = start_pc, end = start_pc + (insn_size * 28); here < end;)
591b725ae77Skettenis {
592b725ae77Skettenis
593b725ae77Skettenis if (media_mode)
594b725ae77Skettenis {
595b725ae77Skettenis int w = read_memory_integer (UNMAKE_ISA32_ADDR (here), insn_size);
596b725ae77Skettenis here += insn_size;
597b725ae77Skettenis if (IS_STQ_R18_R14 (w) || IS_STQ_R18_R15 (w) || IS_STQ_R14_R15 (w)
598b725ae77Skettenis || IS_STL_R14_R15 (w) || IS_STL_R18_R15 (w)
599b725ae77Skettenis || IS_ADDIL_SP_MEDIA (w) || IS_ADDI_SP_MEDIA (w) || IS_PTABSL_R18 (w))
600b725ae77Skettenis {
601b725ae77Skettenis start_pc = here;
602b725ae77Skettenis }
603b725ae77Skettenis else if (IS_MOV_SP_FP (w) || IS_MOV_SP_FP_MEDIA(w))
604b725ae77Skettenis {
605b725ae77Skettenis start_pc = here;
606b725ae77Skettenis updated_fp = 1;
607b725ae77Skettenis }
608b725ae77Skettenis else
609b725ae77Skettenis if (updated_fp)
610b725ae77Skettenis {
611b725ae77Skettenis /* Don't bail out yet, we may have arguments stored in
612b725ae77Skettenis registers here, according to the debug info, so that
613b725ae77Skettenis gdb can print the frames correctly. */
614b725ae77Skettenis start_pc = look_for_args_moves (here - insn_size, media_mode);
615b725ae77Skettenis break;
616b725ae77Skettenis }
617b725ae77Skettenis }
618b725ae77Skettenis else
619b725ae77Skettenis {
620b725ae77Skettenis int w = 0xffff & read_memory_integer (here, insn_size);
621b725ae77Skettenis here += insn_size;
622b725ae77Skettenis
623b725ae77Skettenis if (IS_STS_R0 (w) || IS_STS_PR (w)
624b725ae77Skettenis || IS_MOV_TO_R15 (w) || IS_MOV_R14 (w)
625b725ae77Skettenis || IS_MOV_R0 (w) || IS_ADD_SP_R0 (w) || IS_MOV_R14_R0 (w))
626b725ae77Skettenis {
627b725ae77Skettenis start_pc = here;
628b725ae77Skettenis }
629b725ae77Skettenis else if (IS_MOV_SP_FP (w))
630b725ae77Skettenis {
631b725ae77Skettenis start_pc = here;
632b725ae77Skettenis updated_fp = 1;
633b725ae77Skettenis }
634b725ae77Skettenis else
635b725ae77Skettenis if (updated_fp)
636b725ae77Skettenis {
637b725ae77Skettenis /* Don't bail out yet, we may have arguments stored in
638b725ae77Skettenis registers here, according to the debug info, so that
639b725ae77Skettenis gdb can print the frames correctly. */
640b725ae77Skettenis start_pc = look_for_args_moves (here - insn_size, media_mode);
641b725ae77Skettenis break;
642b725ae77Skettenis }
643b725ae77Skettenis }
644b725ae77Skettenis }
645b725ae77Skettenis
646b725ae77Skettenis return start_pc;
647b725ae77Skettenis }
648b725ae77Skettenis
649b725ae77Skettenis static CORE_ADDR
sh_skip_prologue(CORE_ADDR pc)650b725ae77Skettenis sh_skip_prologue (CORE_ADDR pc)
651b725ae77Skettenis {
652b725ae77Skettenis CORE_ADDR post_prologue_pc;
653b725ae77Skettenis
654b725ae77Skettenis /* See if we can determine the end of the prologue via the symbol table.
655b725ae77Skettenis If so, then return either PC, or the PC after the prologue, whichever
656b725ae77Skettenis is greater. */
657b725ae77Skettenis post_prologue_pc = after_prologue (pc);
658b725ae77Skettenis
659b725ae77Skettenis /* If after_prologue returned a useful address, then use it. Else
660b725ae77Skettenis fall back on the instruction skipping code. */
661b725ae77Skettenis if (post_prologue_pc != 0)
662b725ae77Skettenis return max (pc, post_prologue_pc);
663b725ae77Skettenis else
664b725ae77Skettenis return sh64_skip_prologue_hard_way (pc);
665b725ae77Skettenis }
666b725ae77Skettenis
667b725ae77Skettenis /* Immediately after a function call, return the saved pc.
668b725ae77Skettenis Can't always go through the frames for this because on some machines
669b725ae77Skettenis the new frame is not set up until the new function executes
670b725ae77Skettenis some instructions.
671b725ae77Skettenis
672b725ae77Skettenis The return address is the value saved in the PR register + 4 */
673b725ae77Skettenis static CORE_ADDR
sh_saved_pc_after_call(struct frame_info * frame)674b725ae77Skettenis sh_saved_pc_after_call (struct frame_info *frame)
675b725ae77Skettenis {
676b725ae77Skettenis return (ADDR_BITS_REMOVE (read_register (PR_REGNUM)));
677b725ae77Skettenis }
678b725ae77Skettenis
679b725ae77Skettenis /* Should call_function allocate stack space for a struct return? */
680b725ae77Skettenis static int
sh64_use_struct_convention(int gcc_p,struct type * type)681b725ae77Skettenis sh64_use_struct_convention (int gcc_p, struct type *type)
682b725ae77Skettenis {
683b725ae77Skettenis return (TYPE_LENGTH (type) > 8);
684b725ae77Skettenis }
685b725ae77Skettenis
686b725ae77Skettenis /* Store the address of the place in which to copy the structure the
687b725ae77Skettenis subroutine will return. This is called from call_function.
688b725ae77Skettenis
689b725ae77Skettenis We store structs through a pointer passed in R2 */
690b725ae77Skettenis static void
sh64_store_struct_return(CORE_ADDR addr,CORE_ADDR sp)691b725ae77Skettenis sh64_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
692b725ae77Skettenis {
693b725ae77Skettenis write_register (STRUCT_RETURN_REGNUM, (addr));
694b725ae77Skettenis }
695b725ae77Skettenis
696b725ae77Skettenis /* Disassemble an instruction. */
697b725ae77Skettenis static int
gdb_print_insn_sh(bfd_vma memaddr,disassemble_info * info)698b725ae77Skettenis gdb_print_insn_sh (bfd_vma memaddr, disassemble_info *info)
699b725ae77Skettenis {
700b725ae77Skettenis info->endian = TARGET_BYTE_ORDER;
701b725ae77Skettenis return print_insn_sh (memaddr, info);
702b725ae77Skettenis }
703b725ae77Skettenis
704b725ae77Skettenis /* Given a register number RN as it appears in an assembly
705b725ae77Skettenis instruction, find the corresponding register number in the GDB
706b725ae77Skettenis scheme. */
707b725ae77Skettenis static int
translate_insn_rn(int rn,int media_mode)708b725ae77Skettenis translate_insn_rn (int rn, int media_mode)
709b725ae77Skettenis {
710b725ae77Skettenis /* FIXME: this assumes that the number rn is for a not pseudo
711b725ae77Skettenis register only. */
712b725ae77Skettenis if (media_mode)
713b725ae77Skettenis return rn;
714b725ae77Skettenis else
715b725ae77Skettenis {
716b725ae77Skettenis /* These registers don't have a corresponding compact one. */
717b725ae77Skettenis /* FIXME: This is probably not enough. */
718b725ae77Skettenis #if 0
719b725ae77Skettenis if ((rn >= 16 && rn <= 63) || (rn >= 93 && rn <= 140))
720b725ae77Skettenis return rn;
721b725ae77Skettenis #endif
722b725ae77Skettenis if (rn >= 0 && rn <= R0_C_REGNUM)
723b725ae77Skettenis return R0_C_REGNUM + rn;
724b725ae77Skettenis else
725b725ae77Skettenis return rn;
726b725ae77Skettenis }
727b725ae77Skettenis }
728b725ae77Skettenis
729b725ae77Skettenis /* Given a GDB frame, determine the address of the calling function's
730b725ae77Skettenis frame. This will be used to create a new GDB frame struct, and
731b725ae77Skettenis then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC
732b725ae77Skettenis will be called for the new frame.
733b725ae77Skettenis
734b725ae77Skettenis For us, the frame address is its stack pointer value, so we look up
735b725ae77Skettenis the function prologue to determine the caller's sp value, and return it. */
736b725ae77Skettenis static CORE_ADDR
sh64_frame_chain(struct frame_info * frame)737b725ae77Skettenis sh64_frame_chain (struct frame_info *frame)
738b725ae77Skettenis {
739*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
740b725ae77Skettenis return get_frame_base (frame); /* dummy frame same as caller's frame */
741*11efff7fSkettenis if (get_frame_pc (frame))
742b725ae77Skettenis {
743b725ae77Skettenis int media_mode = pc_is_isa32 (get_frame_pc (frame));
744b725ae77Skettenis int size;
745b725ae77Skettenis if (gdbarch_tdep (current_gdbarch)->sh_abi == SH_ABI_32)
746b725ae77Skettenis size = 4;
747b725ae77Skettenis else
748b725ae77Skettenis size = register_size (current_gdbarch,
749b725ae77Skettenis translate_insn_rn (DEPRECATED_FP_REGNUM,
750b725ae77Skettenis media_mode));
751b725ae77Skettenis return read_memory_integer (get_frame_base (frame)
752b725ae77Skettenis + get_frame_extra_info (frame)->f_offset,
753b725ae77Skettenis size);
754b725ae77Skettenis }
755b725ae77Skettenis else
756b725ae77Skettenis return 0;
757b725ae77Skettenis }
758b725ae77Skettenis
759b725ae77Skettenis static CORE_ADDR
sh64_get_saved_pr(struct frame_info * fi,int pr_regnum)760b725ae77Skettenis sh64_get_saved_pr (struct frame_info *fi, int pr_regnum)
761b725ae77Skettenis {
762b725ae77Skettenis int media_mode = 0;
763b725ae77Skettenis
764b725ae77Skettenis for (; fi; fi = get_next_frame (fi))
765*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
766b725ae77Skettenis /* When the caller requests PR from the dummy frame, we return
767b725ae77Skettenis PC because that's where the previous routine appears to have
768b725ae77Skettenis done a call from. */
769b725ae77Skettenis return deprecated_read_register_dummy (get_frame_pc (fi),
770b725ae77Skettenis get_frame_base (fi), pr_regnum);
771b725ae77Skettenis else
772b725ae77Skettenis {
773b725ae77Skettenis DEPRECATED_FRAME_INIT_SAVED_REGS (fi);
774b725ae77Skettenis if (!get_frame_pc (fi))
775b725ae77Skettenis return 0;
776b725ae77Skettenis
777b725ae77Skettenis media_mode = pc_is_isa32 (get_frame_pc (fi));
778b725ae77Skettenis
779b725ae77Skettenis if (deprecated_get_frame_saved_regs (fi)[pr_regnum] != 0)
780b725ae77Skettenis {
781b725ae77Skettenis int gdb_reg_num = translate_insn_rn (pr_regnum, media_mode);
782b725ae77Skettenis int size = ((gdbarch_tdep (current_gdbarch)->sh_abi == SH_ABI_32)
783b725ae77Skettenis ? 4
784b725ae77Skettenis : register_size (current_gdbarch, gdb_reg_num));
785b725ae77Skettenis return read_memory_integer (deprecated_get_frame_saved_regs (fi)[pr_regnum], size);
786b725ae77Skettenis }
787b725ae77Skettenis }
788b725ae77Skettenis return read_register (pr_regnum);
789b725ae77Skettenis }
790b725ae77Skettenis
791b725ae77Skettenis /* For vectors of 4 floating point registers. */
792b725ae77Skettenis static int
fv_reg_base_num(int fv_regnum)793b725ae77Skettenis fv_reg_base_num (int fv_regnum)
794b725ae77Skettenis {
795b725ae77Skettenis int fp_regnum;
796b725ae77Skettenis
797b725ae77Skettenis fp_regnum = FP0_REGNUM +
798b725ae77Skettenis (fv_regnum - FV0_REGNUM) * 4;
799b725ae77Skettenis return fp_regnum;
800b725ae77Skettenis }
801b725ae77Skettenis
802b725ae77Skettenis /* For double precision floating point registers, i.e 2 fp regs.*/
803b725ae77Skettenis static int
dr_reg_base_num(int dr_regnum)804b725ae77Skettenis dr_reg_base_num (int dr_regnum)
805b725ae77Skettenis {
806b725ae77Skettenis int fp_regnum;
807b725ae77Skettenis
808b725ae77Skettenis fp_regnum = FP0_REGNUM +
809b725ae77Skettenis (dr_regnum - DR0_REGNUM) * 2;
810b725ae77Skettenis return fp_regnum;
811b725ae77Skettenis }
812b725ae77Skettenis
813b725ae77Skettenis /* For pairs of floating point registers */
814b725ae77Skettenis static int
fpp_reg_base_num(int fpp_regnum)815b725ae77Skettenis fpp_reg_base_num (int fpp_regnum)
816b725ae77Skettenis {
817b725ae77Skettenis int fp_regnum;
818b725ae77Skettenis
819b725ae77Skettenis fp_regnum = FP0_REGNUM +
820b725ae77Skettenis (fpp_regnum - FPP0_REGNUM) * 2;
821b725ae77Skettenis return fp_regnum;
822b725ae77Skettenis }
823b725ae77Skettenis
824b725ae77Skettenis static int
is_media_pseudo(int rn)825b725ae77Skettenis is_media_pseudo (int rn)
826b725ae77Skettenis {
827b725ae77Skettenis return (rn >= DR0_REGNUM && rn <= FV_LAST_REGNUM);
828b725ae77Skettenis }
829b725ae77Skettenis
830b725ae77Skettenis static int
sh64_media_reg_base_num(int reg_nr)831b725ae77Skettenis sh64_media_reg_base_num (int reg_nr)
832b725ae77Skettenis {
833b725ae77Skettenis int base_regnum = -1;
834b725ae77Skettenis
835b725ae77Skettenis if (reg_nr >= DR0_REGNUM
836b725ae77Skettenis && reg_nr <= DR_LAST_REGNUM)
837b725ae77Skettenis base_regnum = dr_reg_base_num (reg_nr);
838b725ae77Skettenis
839b725ae77Skettenis else if (reg_nr >= FPP0_REGNUM
840b725ae77Skettenis && reg_nr <= FPP_LAST_REGNUM)
841b725ae77Skettenis base_regnum = fpp_reg_base_num (reg_nr);
842b725ae77Skettenis
843b725ae77Skettenis else if (reg_nr >= FV0_REGNUM
844b725ae77Skettenis && reg_nr <= FV_LAST_REGNUM)
845b725ae77Skettenis base_regnum = fv_reg_base_num (reg_nr);
846b725ae77Skettenis
847b725ae77Skettenis return base_regnum;
848b725ae77Skettenis }
849b725ae77Skettenis
850b725ae77Skettenis /* *INDENT-OFF* */
851b725ae77Skettenis /*
852b725ae77Skettenis SH COMPACT MODE (ISA 16) (all pseudo) 221-272
853b725ae77Skettenis GDB_REGNUM BASE_REGNUM
854b725ae77Skettenis r0_c 221 0
855b725ae77Skettenis r1_c 222 1
856b725ae77Skettenis r2_c 223 2
857b725ae77Skettenis r3_c 224 3
858b725ae77Skettenis r4_c 225 4
859b725ae77Skettenis r5_c 226 5
860b725ae77Skettenis r6_c 227 6
861b725ae77Skettenis r7_c 228 7
862b725ae77Skettenis r8_c 229 8
863b725ae77Skettenis r9_c 230 9
864b725ae77Skettenis r10_c 231 10
865b725ae77Skettenis r11_c 232 11
866b725ae77Skettenis r12_c 233 12
867b725ae77Skettenis r13_c 234 13
868b725ae77Skettenis r14_c 235 14
869b725ae77Skettenis r15_c 236 15
870b725ae77Skettenis
871b725ae77Skettenis pc_c 237 64
872b725ae77Skettenis gbr_c 238 16
873b725ae77Skettenis mach_c 239 17
874b725ae77Skettenis macl_c 240 17
875b725ae77Skettenis pr_c 241 18
876b725ae77Skettenis t_c 242 19
877b725ae77Skettenis fpscr_c 243 76
878b725ae77Skettenis fpul_c 244 109
879b725ae77Skettenis
880b725ae77Skettenis fr0_c 245 77
881b725ae77Skettenis fr1_c 246 78
882b725ae77Skettenis fr2_c 247 79
883b725ae77Skettenis fr3_c 248 80
884b725ae77Skettenis fr4_c 249 81
885b725ae77Skettenis fr5_c 250 82
886b725ae77Skettenis fr6_c 251 83
887b725ae77Skettenis fr7_c 252 84
888b725ae77Skettenis fr8_c 253 85
889b725ae77Skettenis fr9_c 254 86
890b725ae77Skettenis fr10_c 255 87
891b725ae77Skettenis fr11_c 256 88
892b725ae77Skettenis fr12_c 257 89
893b725ae77Skettenis fr13_c 258 90
894b725ae77Skettenis fr14_c 259 91
895b725ae77Skettenis fr15_c 260 92
896b725ae77Skettenis
897b725ae77Skettenis dr0_c 261 77
898b725ae77Skettenis dr2_c 262 79
899b725ae77Skettenis dr4_c 263 81
900b725ae77Skettenis dr6_c 264 83
901b725ae77Skettenis dr8_c 265 85
902b725ae77Skettenis dr10_c 266 87
903b725ae77Skettenis dr12_c 267 89
904b725ae77Skettenis dr14_c 268 91
905b725ae77Skettenis
906b725ae77Skettenis fv0_c 269 77
907b725ae77Skettenis fv4_c 270 81
908b725ae77Skettenis fv8_c 271 85
909b725ae77Skettenis fv12_c 272 91
910b725ae77Skettenis */
911b725ae77Skettenis /* *INDENT-ON* */
912b725ae77Skettenis static int
sh64_compact_reg_base_num(int reg_nr)913b725ae77Skettenis sh64_compact_reg_base_num (int reg_nr)
914b725ae77Skettenis {
915b725ae77Skettenis int base_regnum = -1;
916b725ae77Skettenis
917b725ae77Skettenis /* general register N maps to general register N */
918b725ae77Skettenis if (reg_nr >= R0_C_REGNUM
919b725ae77Skettenis && reg_nr <= R_LAST_C_REGNUM)
920b725ae77Skettenis base_regnum = reg_nr - R0_C_REGNUM;
921b725ae77Skettenis
922b725ae77Skettenis /* floating point register N maps to floating point register N */
923b725ae77Skettenis else if (reg_nr >= FP0_C_REGNUM
924b725ae77Skettenis && reg_nr <= FP_LAST_C_REGNUM)
925b725ae77Skettenis base_regnum = reg_nr - FP0_C_REGNUM + FP0_REGNUM;
926b725ae77Skettenis
927b725ae77Skettenis /* double prec register N maps to base regnum for double prec register N */
928b725ae77Skettenis else if (reg_nr >= DR0_C_REGNUM
929b725ae77Skettenis && reg_nr <= DR_LAST_C_REGNUM)
930b725ae77Skettenis base_regnum = dr_reg_base_num (DR0_REGNUM
931b725ae77Skettenis + reg_nr - DR0_C_REGNUM);
932b725ae77Skettenis
933b725ae77Skettenis /* vector N maps to base regnum for vector register N */
934b725ae77Skettenis else if (reg_nr >= FV0_C_REGNUM
935b725ae77Skettenis && reg_nr <= FV_LAST_C_REGNUM)
936b725ae77Skettenis base_regnum = fv_reg_base_num (FV0_REGNUM
937b725ae77Skettenis + reg_nr - FV0_C_REGNUM);
938b725ae77Skettenis
939b725ae77Skettenis else if (reg_nr == PC_C_REGNUM)
940b725ae77Skettenis base_regnum = PC_REGNUM;
941b725ae77Skettenis
942b725ae77Skettenis else if (reg_nr == GBR_C_REGNUM)
943b725ae77Skettenis base_regnum = 16;
944b725ae77Skettenis
945b725ae77Skettenis else if (reg_nr == MACH_C_REGNUM
946b725ae77Skettenis || reg_nr == MACL_C_REGNUM)
947b725ae77Skettenis base_regnum = 17;
948b725ae77Skettenis
949b725ae77Skettenis else if (reg_nr == PR_C_REGNUM)
950b725ae77Skettenis base_regnum = 18;
951b725ae77Skettenis
952b725ae77Skettenis else if (reg_nr == T_C_REGNUM)
953b725ae77Skettenis base_regnum = 19;
954b725ae77Skettenis
955b725ae77Skettenis else if (reg_nr == FPSCR_C_REGNUM)
956b725ae77Skettenis base_regnum = FPSCR_REGNUM; /*???? this register is a mess. */
957b725ae77Skettenis
958b725ae77Skettenis else if (reg_nr == FPUL_C_REGNUM)
959b725ae77Skettenis base_regnum = FP0_REGNUM + 32;
960b725ae77Skettenis
961b725ae77Skettenis return base_regnum;
962b725ae77Skettenis }
963b725ae77Skettenis
964b725ae77Skettenis /* Given a register number RN (according to the gdb scheme) , return
965b725ae77Skettenis its corresponding architectural register. In media mode, only a
966b725ae77Skettenis subset of the registers is pseudo registers. For compact mode, all
967b725ae77Skettenis the registers are pseudo. */
968b725ae77Skettenis static int
translate_rn_to_arch_reg_num(int rn,int media_mode)969b725ae77Skettenis translate_rn_to_arch_reg_num (int rn, int media_mode)
970b725ae77Skettenis {
971b725ae77Skettenis
972b725ae77Skettenis if (media_mode)
973b725ae77Skettenis {
974b725ae77Skettenis if (!is_media_pseudo (rn))
975b725ae77Skettenis return rn;
976b725ae77Skettenis else
977b725ae77Skettenis return sh64_media_reg_base_num (rn);
978b725ae77Skettenis }
979b725ae77Skettenis else
980b725ae77Skettenis /* All compact registers are pseudo. */
981b725ae77Skettenis return sh64_compact_reg_base_num (rn);
982b725ae77Skettenis }
983b725ae77Skettenis
984b725ae77Skettenis static int
sign_extend(int value,int bits)985b725ae77Skettenis sign_extend (int value, int bits)
986b725ae77Skettenis {
987b725ae77Skettenis value = value & ((1 << bits) - 1);
988b725ae77Skettenis return (value & (1 << (bits - 1))
989b725ae77Skettenis ? value | (~((1 << bits) - 1))
990b725ae77Skettenis : value);
991b725ae77Skettenis }
992b725ae77Skettenis
993b725ae77Skettenis static void
sh64_nofp_frame_init_saved_regs(struct frame_info * fi)994b725ae77Skettenis sh64_nofp_frame_init_saved_regs (struct frame_info *fi)
995b725ae77Skettenis {
996b725ae77Skettenis int *where = (int *) alloca ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (int));
997b725ae77Skettenis int rn;
998b725ae77Skettenis int have_fp = 0;
999b725ae77Skettenis int fp_regnum;
1000b725ae77Skettenis int sp_regnum;
1001b725ae77Skettenis int depth;
1002b725ae77Skettenis int pc;
1003b725ae77Skettenis int opc;
1004b725ae77Skettenis int insn;
1005b725ae77Skettenis int r0_val = 0;
1006b725ae77Skettenis int media_mode = 0;
1007b725ae77Skettenis int insn_size;
1008b725ae77Skettenis int gdb_register_number;
1009b725ae77Skettenis int register_number;
1010b725ae77Skettenis char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi),
1011b725ae77Skettenis get_frame_base (fi));
1012b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1013b725ae77Skettenis
1014b725ae77Skettenis if (deprecated_get_frame_saved_regs (fi) == NULL)
1015b725ae77Skettenis frame_saved_regs_zalloc (fi);
1016b725ae77Skettenis else
1017b725ae77Skettenis memset (deprecated_get_frame_saved_regs (fi), 0, SIZEOF_FRAME_SAVED_REGS);
1018b725ae77Skettenis
1019b725ae77Skettenis if (dummy_regs)
1020b725ae77Skettenis {
1021b725ae77Skettenis /* DANGER! This is ONLY going to work if the char buffer format of
1022b725ae77Skettenis the saved registers is byte-for-byte identical to the
1023b725ae77Skettenis CORE_ADDR regs[NUM_REGS] format used by struct frame_saved_regs! */
1024b725ae77Skettenis memcpy (deprecated_get_frame_saved_regs (fi), dummy_regs, SIZEOF_FRAME_SAVED_REGS);
1025b725ae77Skettenis return;
1026b725ae77Skettenis }
1027b725ae77Skettenis
1028b725ae77Skettenis get_frame_extra_info (fi)->leaf_function = 1;
1029b725ae77Skettenis get_frame_extra_info (fi)->f_offset = 0;
1030b725ae77Skettenis
1031b725ae77Skettenis for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
1032b725ae77Skettenis where[rn] = -1;
1033b725ae77Skettenis
1034b725ae77Skettenis depth = 0;
1035b725ae77Skettenis
1036b725ae77Skettenis /* Loop around examining the prologue insns until we find something
1037b725ae77Skettenis that does not appear to be part of the prologue. But give up
1038b725ae77Skettenis after 20 of them, since we're getting silly then. */
1039b725ae77Skettenis
1040b725ae77Skettenis pc = get_frame_func (fi);
1041b725ae77Skettenis if (!pc)
1042b725ae77Skettenis {
1043b725ae77Skettenis deprecated_update_frame_pc_hack (fi, 0);
1044b725ae77Skettenis return;
1045b725ae77Skettenis }
1046b725ae77Skettenis
1047b725ae77Skettenis if (pc_is_isa32 (pc))
1048b725ae77Skettenis {
1049b725ae77Skettenis media_mode = 1;
1050b725ae77Skettenis insn_size = 4;
1051b725ae77Skettenis }
1052b725ae77Skettenis else
1053b725ae77Skettenis {
1054b725ae77Skettenis media_mode = 0;
1055b725ae77Skettenis insn_size = 2;
1056b725ae77Skettenis }
1057b725ae77Skettenis
1058b725ae77Skettenis /* The frame pointer register is general register 14 in shmedia and
1059b725ae77Skettenis shcompact modes. In sh compact it is a pseudo register. Same goes
1060b725ae77Skettenis for the stack pointer register, which is register 15. */
1061b725ae77Skettenis fp_regnum = translate_insn_rn (DEPRECATED_FP_REGNUM, media_mode);
1062b725ae77Skettenis sp_regnum = translate_insn_rn (SP_REGNUM, media_mode);
1063b725ae77Skettenis
1064b725ae77Skettenis for (opc = pc + (insn_size * 28); pc < opc; pc += insn_size)
1065b725ae77Skettenis {
1066b725ae77Skettenis insn = read_memory_integer (media_mode ? UNMAKE_ISA32_ADDR (pc) : pc,
1067b725ae77Skettenis insn_size);
1068b725ae77Skettenis
1069b725ae77Skettenis if (media_mode == 0)
1070b725ae77Skettenis {
1071b725ae77Skettenis if (IS_STS_PR (insn))
1072b725ae77Skettenis {
1073b725ae77Skettenis int next_insn = read_memory_integer (pc + insn_size, insn_size);
1074b725ae77Skettenis if (IS_MOV_TO_R15 (next_insn))
1075b725ae77Skettenis {
1076b725ae77Skettenis int reg_nr = PR_C_REGNUM;
1077b725ae77Skettenis
1078b725ae77Skettenis where[reg_nr] = depth - ((((next_insn & 0xf) ^ 0x8) - 0x8) << 2);
1079b725ae77Skettenis get_frame_extra_info (fi)->leaf_function = 0;
1080b725ae77Skettenis pc += insn_size;
1081b725ae77Skettenis }
1082b725ae77Skettenis }
1083b725ae77Skettenis else if (IS_MOV_R14 (insn))
1084b725ae77Skettenis {
1085b725ae77Skettenis where[fp_regnum] = depth - ((((insn & 0xf) ^ 0x8) - 0x8) << 2);
1086b725ae77Skettenis }
1087b725ae77Skettenis
1088b725ae77Skettenis else if (IS_MOV_R0 (insn))
1089b725ae77Skettenis {
1090b725ae77Skettenis /* Put in R0 the offset from SP at which to store some
1091b725ae77Skettenis registers. We are interested in this value, because it
1092b725ae77Skettenis will tell us where the given registers are stored within
1093b725ae77Skettenis the frame. */
1094b725ae77Skettenis r0_val = ((insn & 0xff) ^ 0x80) - 0x80;
1095b725ae77Skettenis }
1096b725ae77Skettenis else if (IS_ADD_SP_R0 (insn))
1097b725ae77Skettenis {
1098b725ae77Skettenis /* This instruction still prepares r0, but we don't care.
1099b725ae77Skettenis We already have the offset in r0_val. */
1100b725ae77Skettenis }
1101b725ae77Skettenis else if (IS_STS_R0 (insn))
1102b725ae77Skettenis {
1103b725ae77Skettenis /* Store PR at r0_val-4 from SP. Decrement r0 by 4*/
1104b725ae77Skettenis int reg_nr = PR_C_REGNUM;
1105b725ae77Skettenis where[reg_nr] = depth - (r0_val - 4);
1106b725ae77Skettenis r0_val -= 4;
1107b725ae77Skettenis get_frame_extra_info (fi)->leaf_function = 0;
1108b725ae77Skettenis }
1109b725ae77Skettenis else if (IS_MOV_R14_R0 (insn))
1110b725ae77Skettenis {
1111b725ae77Skettenis /* Store R14 at r0_val-4 from SP. Decrement r0 by 4 */
1112b725ae77Skettenis where[fp_regnum] = depth - (r0_val - 4);
1113b725ae77Skettenis r0_val -= 4;
1114b725ae77Skettenis }
1115b725ae77Skettenis
1116b725ae77Skettenis else if (IS_ADD_SP (insn))
1117b725ae77Skettenis {
1118b725ae77Skettenis depth -= ((insn & 0xff) ^ 0x80) - 0x80;
1119b725ae77Skettenis }
1120b725ae77Skettenis else if (IS_MOV_SP_FP (insn))
1121b725ae77Skettenis break;
1122b725ae77Skettenis }
1123b725ae77Skettenis else
1124b725ae77Skettenis {
1125b725ae77Skettenis if (IS_ADDIL_SP_MEDIA (insn)
1126b725ae77Skettenis || IS_ADDI_SP_MEDIA (insn))
1127b725ae77Skettenis {
1128b725ae77Skettenis depth -= sign_extend ((((insn & 0xffc00) ^ 0x80000) - 0x80000) >> 10, 9);
1129b725ae77Skettenis }
1130b725ae77Skettenis
1131b725ae77Skettenis else if (IS_STQ_R18_R15 (insn))
1132b725ae77Skettenis {
1133b725ae77Skettenis where[PR_REGNUM] =
1134b725ae77Skettenis depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
1135b725ae77Skettenis get_frame_extra_info (fi)->leaf_function = 0;
1136b725ae77Skettenis }
1137b725ae77Skettenis
1138b725ae77Skettenis else if (IS_STL_R18_R15 (insn))
1139b725ae77Skettenis {
1140b725ae77Skettenis where[PR_REGNUM] =
1141b725ae77Skettenis depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
1142b725ae77Skettenis get_frame_extra_info (fi)->leaf_function = 0;
1143b725ae77Skettenis }
1144b725ae77Skettenis
1145b725ae77Skettenis else if (IS_STQ_R14_R15 (insn))
1146b725ae77Skettenis {
1147b725ae77Skettenis where[fp_regnum] = depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 3);
1148b725ae77Skettenis }
1149b725ae77Skettenis
1150b725ae77Skettenis else if (IS_STL_R14_R15 (insn))
1151b725ae77Skettenis {
1152b725ae77Skettenis where[fp_regnum] = depth - (sign_extend ((insn & 0xffc00) >> 10, 9) << 2);
1153b725ae77Skettenis }
1154b725ae77Skettenis
1155b725ae77Skettenis else if (IS_MOV_SP_FP_MEDIA (insn))
1156b725ae77Skettenis break;
1157b725ae77Skettenis }
1158b725ae77Skettenis }
1159b725ae77Skettenis
1160b725ae77Skettenis /* Now we know how deep things are, we can work out their addresses. */
1161b725ae77Skettenis for (rn = 0; rn < NUM_REGS + NUM_PSEUDO_REGS; rn++)
1162b725ae77Skettenis {
1163b725ae77Skettenis register_number = translate_rn_to_arch_reg_num (rn, media_mode);
1164b725ae77Skettenis
1165b725ae77Skettenis if (where[rn] >= 0)
1166b725ae77Skettenis {
1167b725ae77Skettenis if (rn == fp_regnum)
1168b725ae77Skettenis have_fp = 1;
1169b725ae77Skettenis
1170b725ae77Skettenis /* Watch out! saved_regs is only for the real registers, and
1171b725ae77Skettenis doesn't include space for the pseudo registers. */
1172b725ae77Skettenis deprecated_get_frame_saved_regs (fi)[register_number]
1173b725ae77Skettenis = get_frame_base (fi) - where[rn] + depth;
1174b725ae77Skettenis }
1175b725ae77Skettenis else
1176b725ae77Skettenis deprecated_get_frame_saved_regs (fi)[register_number] = 0;
1177b725ae77Skettenis }
1178b725ae77Skettenis
1179b725ae77Skettenis if (have_fp)
1180b725ae77Skettenis {
1181b725ae77Skettenis /* SP_REGNUM is 15. For shmedia 15 is the real register. For
1182b725ae77Skettenis shcompact 15 is the arch register corresponding to the pseudo
1183b725ae77Skettenis register r15 which still is the SP register. */
1184b725ae77Skettenis /* The place on the stack where fp is stored contains the sp of
1185b725ae77Skettenis the caller. */
1186b725ae77Skettenis /* Again, saved_registers contains only space for the real
1187b725ae77Skettenis registers, so we store in DEPRECATED_FP_REGNUM position. */
1188b725ae77Skettenis int size;
1189b725ae77Skettenis if (tdep->sh_abi == SH_ABI_32)
1190b725ae77Skettenis size = 4;
1191b725ae77Skettenis else
1192b725ae77Skettenis size = register_size (current_gdbarch, fp_regnum);
1193b725ae77Skettenis deprecated_get_frame_saved_regs (fi)[sp_regnum]
1194b725ae77Skettenis = read_memory_integer (deprecated_get_frame_saved_regs (fi)[fp_regnum],
1195b725ae77Skettenis size);
1196b725ae77Skettenis }
1197b725ae77Skettenis else
1198b725ae77Skettenis deprecated_get_frame_saved_regs (fi)[sp_regnum] = get_frame_base (fi);
1199b725ae77Skettenis
1200b725ae77Skettenis get_frame_extra_info (fi)->f_offset = depth - where[fp_regnum];
1201b725ae77Skettenis }
1202b725ae77Skettenis
1203b725ae77Skettenis /* Initialize the extra info saved in a FRAME */
1204b725ae77Skettenis static void
sh64_init_extra_frame_info(int fromleaf,struct frame_info * fi)1205b725ae77Skettenis sh64_init_extra_frame_info (int fromleaf, struct frame_info *fi)
1206b725ae77Skettenis {
1207b725ae77Skettenis int media_mode = pc_is_isa32 (get_frame_pc (fi));
1208b725ae77Skettenis
1209b725ae77Skettenis frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
1210b725ae77Skettenis
1211b725ae77Skettenis if (get_next_frame (fi))
1212b725ae77Skettenis deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
1213b725ae77Skettenis
1214*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
1215b725ae77Skettenis {
1216b725ae77Skettenis /* We need to setup fi->frame here because call_function_by_hand
1217b725ae77Skettenis gets it wrong by assuming it's always FP. */
1218b725ae77Skettenis deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
1219b725ae77Skettenis get_frame_extra_info (fi)->return_pc =
1220b725ae77Skettenis deprecated_read_register_dummy (get_frame_pc (fi),
1221b725ae77Skettenis get_frame_base (fi), PC_REGNUM);
1222*11efff7fSkettenis get_frame_extra_info (fi)->f_offset = -4;
1223b725ae77Skettenis get_frame_extra_info (fi)->leaf_function = 0;
1224b725ae77Skettenis return;
1225b725ae77Skettenis }
1226b725ae77Skettenis else
1227b725ae77Skettenis {
1228b725ae77Skettenis DEPRECATED_FRAME_INIT_SAVED_REGS (fi);
1229b725ae77Skettenis get_frame_extra_info (fi)->return_pc =
1230b725ae77Skettenis sh64_get_saved_pr (fi, PR_REGNUM);
1231b725ae77Skettenis }
1232b725ae77Skettenis }
1233b725ae77Skettenis
1234b725ae77Skettenis static void
sh64_get_saved_register(char * raw_buffer,int * optimized,CORE_ADDR * addrp,struct frame_info * frame,int regnum,enum lval_type * lval)1235b725ae77Skettenis sh64_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp,
1236b725ae77Skettenis struct frame_info *frame, int regnum,
1237b725ae77Skettenis enum lval_type *lval)
1238b725ae77Skettenis {
1239b725ae77Skettenis int media_mode;
1240b725ae77Skettenis int live_regnum = regnum;
1241b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1242b725ae77Skettenis
1243b725ae77Skettenis if (!target_has_registers)
1244b725ae77Skettenis error ("No registers.");
1245b725ae77Skettenis
1246b725ae77Skettenis /* Normal systems don't optimize out things with register numbers. */
1247b725ae77Skettenis if (optimized != NULL)
1248b725ae77Skettenis *optimized = 0;
1249b725ae77Skettenis
1250b725ae77Skettenis if (addrp) /* default assumption: not found in memory */
1251b725ae77Skettenis *addrp = 0;
1252b725ae77Skettenis
1253b725ae77Skettenis if (raw_buffer)
1254b725ae77Skettenis memset (raw_buffer, 0, sizeof (raw_buffer));
1255b725ae77Skettenis
1256b725ae77Skettenis /* We must do this here, before the following while loop changes
1257b725ae77Skettenis frame, and makes it NULL. If this is a media register number,
1258b725ae77Skettenis but we are in compact mode, it will become the corresponding
1259b725ae77Skettenis compact pseudo register. If there is no corresponding compact
1260b725ae77Skettenis pseudo-register what do we do?*/
1261b725ae77Skettenis media_mode = pc_is_isa32 (get_frame_pc (frame));
1262b725ae77Skettenis live_regnum = translate_insn_rn (regnum, media_mode);
1263b725ae77Skettenis
1264b725ae77Skettenis /* Note: since the current frame's registers could only have been
1265b725ae77Skettenis saved by frames INTERIOR TO the current frame, we skip examining
1266b725ae77Skettenis the current frame itself: otherwise, we would be getting the
1267b725ae77Skettenis previous frame's registers which were saved by the current frame. */
1268b725ae77Skettenis
1269b725ae77Skettenis while (frame && ((frame = get_next_frame (frame)) != NULL))
1270b725ae77Skettenis {
1271*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
1272b725ae77Skettenis {
1273b725ae77Skettenis if (lval) /* found it in a CALL_DUMMY frame */
1274b725ae77Skettenis *lval = not_lval;
1275b725ae77Skettenis if (raw_buffer)
1276b725ae77Skettenis memcpy (raw_buffer,
1277b725ae77Skettenis (deprecated_generic_find_dummy_frame (get_frame_pc (frame), get_frame_base (frame))
1278b725ae77Skettenis + DEPRECATED_REGISTER_BYTE (regnum)),
1279b725ae77Skettenis register_size (current_gdbarch, regnum));
1280b725ae77Skettenis return;
1281b725ae77Skettenis }
1282b725ae77Skettenis
1283b725ae77Skettenis DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
1284b725ae77Skettenis if (deprecated_get_frame_saved_regs (frame) != NULL
1285b725ae77Skettenis && deprecated_get_frame_saved_regs (frame)[regnum] != 0)
1286b725ae77Skettenis {
1287b725ae77Skettenis if (lval) /* found it saved on the stack */
1288b725ae77Skettenis *lval = lval_memory;
1289b725ae77Skettenis if (regnum == SP_REGNUM)
1290b725ae77Skettenis {
1291b725ae77Skettenis if (raw_buffer) /* SP register treated specially */
1292b725ae77Skettenis store_unsigned_integer (raw_buffer,
1293b725ae77Skettenis register_size (current_gdbarch,
1294b725ae77Skettenis regnum),
1295b725ae77Skettenis deprecated_get_frame_saved_regs (frame)[regnum]);
1296b725ae77Skettenis }
1297b725ae77Skettenis else
1298b725ae77Skettenis { /* any other register */
1299b725ae77Skettenis
1300b725ae77Skettenis if (addrp)
1301b725ae77Skettenis *addrp = deprecated_get_frame_saved_regs (frame)[regnum];
1302b725ae77Skettenis if (raw_buffer)
1303b725ae77Skettenis {
1304b725ae77Skettenis int size;
1305b725ae77Skettenis if (tdep->sh_abi == SH_ABI_32
1306b725ae77Skettenis && (live_regnum == DEPRECATED_FP_REGNUM
1307b725ae77Skettenis || live_regnum == PR_REGNUM))
1308b725ae77Skettenis size = 4;
1309b725ae77Skettenis else
1310b725ae77Skettenis size = register_size (current_gdbarch, live_regnum);
1311b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
1312b725ae77Skettenis read_memory (deprecated_get_frame_saved_regs (frame)[regnum],
1313b725ae77Skettenis raw_buffer, size);
1314b725ae77Skettenis else
1315b725ae77Skettenis read_memory (deprecated_get_frame_saved_regs (frame)[regnum],
1316b725ae77Skettenis raw_buffer
1317b725ae77Skettenis + register_size (current_gdbarch, live_regnum)
1318b725ae77Skettenis - size,
1319b725ae77Skettenis size);
1320b725ae77Skettenis }
1321b725ae77Skettenis }
1322b725ae77Skettenis return;
1323b725ae77Skettenis }
1324b725ae77Skettenis }
1325b725ae77Skettenis
1326b725ae77Skettenis /* If we get thru the loop to this point, it means the register was
1327b725ae77Skettenis not saved in any frame. Return the actual live-register value. */
1328b725ae77Skettenis
1329b725ae77Skettenis if (lval) /* found it in a live register */
1330b725ae77Skettenis *lval = lval_register;
1331b725ae77Skettenis if (addrp)
1332b725ae77Skettenis *addrp = DEPRECATED_REGISTER_BYTE (live_regnum);
1333b725ae77Skettenis if (raw_buffer)
1334b725ae77Skettenis deprecated_read_register_gen (live_regnum, raw_buffer);
1335b725ae77Skettenis }
1336b725ae77Skettenis
1337b725ae77Skettenis static CORE_ADDR
sh64_extract_struct_value_address(struct regcache * regcache)1338b725ae77Skettenis sh64_extract_struct_value_address (struct regcache *regcache)
1339b725ae77Skettenis {
1340b725ae77Skettenis /* FIXME: cagney/2004-01-17: Does the ABI guarantee that the return
1341b725ae77Skettenis address regster is preserved across function calls? Probably
1342b725ae77Skettenis not, making this function wrong. */
1343b725ae77Skettenis ULONGEST val;
1344b725ae77Skettenis regcache_raw_read_unsigned (regcache, STRUCT_RETURN_REGNUM, &val);
1345b725ae77Skettenis return val;
1346b725ae77Skettenis }
1347b725ae77Skettenis
1348b725ae77Skettenis static CORE_ADDR
sh_frame_saved_pc(struct frame_info * frame)1349b725ae77Skettenis sh_frame_saved_pc (struct frame_info *frame)
1350b725ae77Skettenis {
1351b725ae77Skettenis return (get_frame_extra_info (frame)->return_pc);
1352b725ae77Skettenis }
1353b725ae77Skettenis
1354b725ae77Skettenis /* Discard from the stack the innermost frame, restoring all saved registers.
1355b725ae77Skettenis Used in the 'return' command. */
1356b725ae77Skettenis static void
sh64_pop_frame(void)1357b725ae77Skettenis sh64_pop_frame (void)
1358b725ae77Skettenis {
1359b725ae77Skettenis struct frame_info *frame = get_current_frame ();
1360b725ae77Skettenis CORE_ADDR fp;
1361b725ae77Skettenis int regnum;
1362b725ae77Skettenis struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
1363b725ae77Skettenis
1364b725ae77Skettenis int media_mode = pc_is_isa32 (get_frame_pc (frame));
1365b725ae77Skettenis
1366*11efff7fSkettenis if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
1367*11efff7fSkettenis deprecated_pop_dummy_frame ();
1368b725ae77Skettenis else
1369b725ae77Skettenis {
1370b725ae77Skettenis fp = get_frame_base (frame);
1371b725ae77Skettenis DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
1372b725ae77Skettenis
1373b725ae77Skettenis /* Copy regs from where they were saved in the frame */
1374b725ae77Skettenis for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
1375b725ae77Skettenis if (deprecated_get_frame_saved_regs (frame)[regnum])
1376b725ae77Skettenis {
1377b725ae77Skettenis int size;
1378b725ae77Skettenis if (tdep->sh_abi == SH_ABI_32
1379b725ae77Skettenis && (regnum == DEPRECATED_FP_REGNUM
1380b725ae77Skettenis || regnum == PR_REGNUM))
1381b725ae77Skettenis size = 4;
1382b725ae77Skettenis else
1383b725ae77Skettenis size = register_size (current_gdbarch,
1384b725ae77Skettenis translate_insn_rn (regnum, media_mode));
1385b725ae77Skettenis write_register (regnum,
1386b725ae77Skettenis read_memory_integer (deprecated_get_frame_saved_regs (frame)[regnum],
1387b725ae77Skettenis size));
1388b725ae77Skettenis }
1389b725ae77Skettenis
1390b725ae77Skettenis write_register (PC_REGNUM, get_frame_extra_info (frame)->return_pc);
1391b725ae77Skettenis write_register (SP_REGNUM, fp + 8);
1392b725ae77Skettenis }
1393b725ae77Skettenis flush_cached_frames ();
1394b725ae77Skettenis }
1395b725ae77Skettenis
1396b725ae77Skettenis static CORE_ADDR
sh_frame_align(struct gdbarch * ignore,CORE_ADDR sp)1397b725ae77Skettenis sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp)
1398b725ae77Skettenis {
1399b725ae77Skettenis return sp & ~3;
1400b725ae77Skettenis }
1401b725ae77Skettenis
1402b725ae77Skettenis /* Function: push_arguments
1403b725ae77Skettenis Setup the function arguments for calling a function in the inferior.
1404b725ae77Skettenis
1405b725ae77Skettenis On the Renesas SH architecture, there are four registers (R4 to R7)
1406b725ae77Skettenis which are dedicated for passing function arguments. Up to the first
1407b725ae77Skettenis four arguments (depending on size) may go into these registers.
1408b725ae77Skettenis The rest go on the stack.
1409b725ae77Skettenis
1410b725ae77Skettenis Arguments that are smaller than 4 bytes will still take up a whole
1411b725ae77Skettenis register or a whole 32-bit word on the stack, and will be
1412b725ae77Skettenis right-justified in the register or the stack word. This includes
1413b725ae77Skettenis chars, shorts, and small aggregate types.
1414b725ae77Skettenis
1415b725ae77Skettenis Arguments that are larger than 4 bytes may be split between two or
1416b725ae77Skettenis more registers. If there are not enough registers free, an argument
1417b725ae77Skettenis may be passed partly in a register (or registers), and partly on the
1418b725ae77Skettenis stack. This includes doubles, long longs, and larger aggregates.
1419b725ae77Skettenis As far as I know, there is no upper limit to the size of aggregates
1420b725ae77Skettenis that will be passed in this way; in other words, the convention of
1421b725ae77Skettenis passing a pointer to a large aggregate instead of a copy is not used.
1422b725ae77Skettenis
1423b725ae77Skettenis An exceptional case exists for struct arguments (and possibly other
1424b725ae77Skettenis aggregates such as arrays) if the size is larger than 4 bytes but
1425b725ae77Skettenis not a multiple of 4 bytes. In this case the argument is never split
1426b725ae77Skettenis between the registers and the stack, but instead is copied in its
1427b725ae77Skettenis entirety onto the stack, AND also copied into as many registers as
1428b725ae77Skettenis there is room for. In other words, space in registers permitting,
1429b725ae77Skettenis two copies of the same argument are passed in. As far as I can tell,
1430b725ae77Skettenis only the one on the stack is used, although that may be a function
1431b725ae77Skettenis of the level of compiler optimization. I suspect this is a compiler
1432b725ae77Skettenis bug. Arguments of these odd sizes are left-justified within the
1433b725ae77Skettenis word (as opposed to arguments smaller than 4 bytes, which are
1434b725ae77Skettenis right-justified).
1435b725ae77Skettenis
1436b725ae77Skettenis If the function is to return an aggregate type such as a struct, it
1437b725ae77Skettenis is either returned in the normal return value register R0 (if its
1438b725ae77Skettenis size is no greater than one byte), or else the caller must allocate
1439b725ae77Skettenis space into which the callee will copy the return value (if the size
1440b725ae77Skettenis is greater than one byte). In this case, a pointer to the return
1441b725ae77Skettenis value location is passed into the callee in register R2, which does
1442b725ae77Skettenis not displace any of the other arguments passed in via registers R4
1443b725ae77Skettenis to R7. */
1444b725ae77Skettenis
1445b725ae77Skettenis /* R2-R9 for integer types and integer equivalent (char, pointers) and
1446b725ae77Skettenis non-scalar (struct, union) elements (even if the elements are
1447b725ae77Skettenis floats).
1448b725ae77Skettenis FR0-FR11 for single precision floating point (float)
1449b725ae77Skettenis DR0-DR10 for double precision floating point (double)
1450b725ae77Skettenis
1451b725ae77Skettenis If a float is argument number 3 (for instance) and arguments number
1452b725ae77Skettenis 1,2, and 4 are integer, the mapping will be:
1453b725ae77Skettenis arg1 -->R2, arg2 --> R3, arg3 -->FR0, arg4 --> R5. I.e. R4 is not used.
1454b725ae77Skettenis
1455b725ae77Skettenis If a float is argument number 10 (for instance) and arguments number
1456b725ae77Skettenis 1 through 10 are integer, the mapping will be:
1457b725ae77Skettenis arg1->R2, arg2->R3, arg3->R4, arg4->R5, arg5->R6, arg6->R7, arg7->R8,
1458b725ae77Skettenis arg8->R9, arg9->(0,SP)stack(8-byte aligned), arg10->FR0, arg11->stack(16,SP).
1459b725ae77Skettenis I.e. there is hole in the stack.
1460b725ae77Skettenis
1461b725ae77Skettenis Different rules apply for variable arguments functions, and for functions
1462b725ae77Skettenis for which the prototype is not known. */
1463b725ae77Skettenis
1464b725ae77Skettenis static CORE_ADDR
sh64_push_arguments(int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)1465b725ae77Skettenis sh64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
1466b725ae77Skettenis int struct_return, CORE_ADDR struct_addr)
1467b725ae77Skettenis {
1468b725ae77Skettenis int stack_offset, stack_alloc;
1469b725ae77Skettenis int int_argreg;
1470b725ae77Skettenis int float_argreg;
1471b725ae77Skettenis int double_argreg;
1472b725ae77Skettenis int float_arg_index = 0;
1473b725ae77Skettenis int double_arg_index = 0;
1474b725ae77Skettenis int argnum;
1475b725ae77Skettenis struct type *type;
1476b725ae77Skettenis CORE_ADDR regval;
1477b725ae77Skettenis char *val;
1478b725ae77Skettenis char valbuf[8];
1479b725ae77Skettenis char valbuf_tmp[8];
1480b725ae77Skettenis int len;
1481b725ae77Skettenis int argreg_size;
1482b725ae77Skettenis int fp_args[12];
1483b725ae77Skettenis
1484b725ae77Skettenis memset (fp_args, 0, sizeof (fp_args));
1485b725ae77Skettenis
1486b725ae77Skettenis /* first force sp to a 8-byte alignment */
1487b725ae77Skettenis sp = sp & ~7;
1488b725ae77Skettenis
1489b725ae77Skettenis /* The "struct return pointer" pseudo-argument has its own dedicated
1490b725ae77Skettenis register */
1491b725ae77Skettenis
1492b725ae77Skettenis if (struct_return)
1493b725ae77Skettenis write_register (STRUCT_RETURN_REGNUM, struct_addr);
1494b725ae77Skettenis
1495b725ae77Skettenis /* Now make sure there's space on the stack */
1496b725ae77Skettenis for (argnum = 0, stack_alloc = 0; argnum < nargs; argnum++)
1497b725ae77Skettenis stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 7) & ~7);
1498b725ae77Skettenis sp -= stack_alloc; /* make room on stack for args */
1499b725ae77Skettenis
1500b725ae77Skettenis /* Now load as many as possible of the first arguments into
1501b725ae77Skettenis registers, and push the rest onto the stack. There are 64 bytes
1502b725ae77Skettenis in eight registers available. Loop thru args from first to last. */
1503b725ae77Skettenis
1504b725ae77Skettenis int_argreg = ARG0_REGNUM;
1505b725ae77Skettenis float_argreg = FP0_REGNUM;
1506b725ae77Skettenis double_argreg = DR0_REGNUM;
1507b725ae77Skettenis
1508b725ae77Skettenis for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
1509b725ae77Skettenis {
1510b725ae77Skettenis type = VALUE_TYPE (args[argnum]);
1511b725ae77Skettenis len = TYPE_LENGTH (type);
1512b725ae77Skettenis memset (valbuf, 0, sizeof (valbuf));
1513b725ae77Skettenis
1514b725ae77Skettenis if (TYPE_CODE (type) != TYPE_CODE_FLT)
1515b725ae77Skettenis {
1516b725ae77Skettenis argreg_size = register_size (current_gdbarch, int_argreg);
1517b725ae77Skettenis
1518b725ae77Skettenis if (len < argreg_size)
1519b725ae77Skettenis {
1520b725ae77Skettenis /* value gets right-justified in the register or stack word */
1521b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
1522b725ae77Skettenis memcpy (valbuf + argreg_size - len,
1523b725ae77Skettenis (char *) VALUE_CONTENTS (args[argnum]), len);
1524b725ae77Skettenis else
1525b725ae77Skettenis memcpy (valbuf, (char *) VALUE_CONTENTS (args[argnum]), len);
1526b725ae77Skettenis
1527b725ae77Skettenis val = valbuf;
1528b725ae77Skettenis }
1529b725ae77Skettenis else
1530b725ae77Skettenis val = (char *) VALUE_CONTENTS (args[argnum]);
1531b725ae77Skettenis
1532b725ae77Skettenis while (len > 0)
1533b725ae77Skettenis {
1534b725ae77Skettenis if (int_argreg > ARGLAST_REGNUM)
1535b725ae77Skettenis {
1536b725ae77Skettenis /* must go on the stack */
1537b725ae77Skettenis write_memory (sp + stack_offset, val, argreg_size);
1538b725ae77Skettenis stack_offset += 8;/*argreg_size;*/
1539b725ae77Skettenis }
1540b725ae77Skettenis /* NOTE WELL!!!!! This is not an "else if" clause!!!
1541b725ae77Skettenis That's because some *&^%$ things get passed on the stack
1542b725ae77Skettenis AND in the registers! */
1543b725ae77Skettenis if (int_argreg <= ARGLAST_REGNUM)
1544b725ae77Skettenis {
1545b725ae77Skettenis /* there's room in a register */
1546b725ae77Skettenis regval = extract_unsigned_integer (val, argreg_size);
1547b725ae77Skettenis write_register (int_argreg, regval);
1548b725ae77Skettenis }
1549b725ae77Skettenis /* Store the value 8 bytes at a time. This means that
1550b725ae77Skettenis things larger than 8 bytes may go partly in registers
1551b725ae77Skettenis and partly on the stack. FIXME: argreg is incremented
1552b725ae77Skettenis before we use its size. */
1553b725ae77Skettenis len -= argreg_size;
1554b725ae77Skettenis val += argreg_size;
1555b725ae77Skettenis int_argreg++;
1556b725ae77Skettenis }
1557b725ae77Skettenis }
1558b725ae77Skettenis else
1559b725ae77Skettenis {
1560b725ae77Skettenis val = (char *) VALUE_CONTENTS (args[argnum]);
1561b725ae77Skettenis if (len == 4)
1562b725ae77Skettenis {
1563b725ae77Skettenis /* Where is it going to be stored? */
1564b725ae77Skettenis while (fp_args[float_arg_index])
1565b725ae77Skettenis float_arg_index ++;
1566b725ae77Skettenis
1567b725ae77Skettenis /* Now float_argreg points to the register where it
1568b725ae77Skettenis should be stored. Are we still within the allowed
1569b725ae77Skettenis register set? */
1570b725ae77Skettenis if (float_arg_index <= FLOAT_ARGLAST_REGNUM)
1571b725ae77Skettenis {
1572b725ae77Skettenis /* Goes in FR0...FR11 */
1573b725ae77Skettenis deprecated_write_register_gen (FP0_REGNUM + float_arg_index,
1574b725ae77Skettenis val);
1575b725ae77Skettenis fp_args[float_arg_index] = 1;
1576b725ae77Skettenis /* Skip the corresponding general argument register. */
1577b725ae77Skettenis int_argreg ++;
1578b725ae77Skettenis }
1579b725ae77Skettenis else
1580b725ae77Skettenis ;
1581b725ae77Skettenis /* Store it as the integers, 8 bytes at the time, if
1582b725ae77Skettenis necessary spilling on the stack. */
1583b725ae77Skettenis
1584b725ae77Skettenis }
1585b725ae77Skettenis else if (len == 8)
1586b725ae77Skettenis {
1587b725ae77Skettenis /* Where is it going to be stored? */
1588b725ae77Skettenis while (fp_args[double_arg_index])
1589b725ae77Skettenis double_arg_index += 2;
1590b725ae77Skettenis /* Now double_argreg points to the register
1591b725ae77Skettenis where it should be stored.
1592b725ae77Skettenis Are we still within the allowed register set? */
1593b725ae77Skettenis if (double_arg_index < FLOAT_ARGLAST_REGNUM)
1594b725ae77Skettenis {
1595b725ae77Skettenis /* Goes in DR0...DR10 */
1596b725ae77Skettenis /* The numbering of the DRi registers is consecutive,
1597b725ae77Skettenis i.e. includes odd numbers. */
1598b725ae77Skettenis int double_register_offset = double_arg_index / 2;
1599b725ae77Skettenis int regnum = DR0_REGNUM +
1600b725ae77Skettenis double_register_offset;
1601b725ae77Skettenis #if 0
1602b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
1603b725ae77Skettenis {
1604b725ae77Skettenis memset (valbuf_tmp, 0, sizeof (valbuf_tmp));
1605b725ae77Skettenis DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum,
1606b725ae77Skettenis type, val,
1607b725ae77Skettenis valbuf_tmp);
1608b725ae77Skettenis val = valbuf_tmp;
1609b725ae77Skettenis }
1610b725ae77Skettenis #endif
1611b725ae77Skettenis /* Note: must use write_register_gen here instead
1612b725ae77Skettenis of regcache_raw_write, because
1613b725ae77Skettenis regcache_raw_write works only for real
1614b725ae77Skettenis registers, not pseudo. write_register_gen will
1615b725ae77Skettenis call the gdbarch function to do register
1616b725ae77Skettenis writes, and that will properly know how to deal
1617b725ae77Skettenis with pseudoregs. */
1618b725ae77Skettenis deprecated_write_register_gen (regnum, val);
1619b725ae77Skettenis fp_args[double_arg_index] = 1;
1620b725ae77Skettenis fp_args[double_arg_index + 1] = 1;
1621b725ae77Skettenis /* Skip the corresponding general argument register. */
1622b725ae77Skettenis int_argreg ++;
1623b725ae77Skettenis }
1624b725ae77Skettenis else
1625b725ae77Skettenis ;
1626b725ae77Skettenis /* Store it as the integers, 8 bytes at the time, if
1627b725ae77Skettenis necessary spilling on the stack. */
1628b725ae77Skettenis }
1629b725ae77Skettenis }
1630b725ae77Skettenis }
1631b725ae77Skettenis return sp;
1632b725ae77Skettenis }
1633b725ae77Skettenis
1634b725ae77Skettenis /* Function: push_return_address (pc)
1635b725ae77Skettenis Set up the return address for the inferior function call.
1636b725ae77Skettenis Needed for targets where we don't actually execute a JSR/BSR instruction */
1637b725ae77Skettenis
1638b725ae77Skettenis static CORE_ADDR
sh64_push_return_address(CORE_ADDR pc,CORE_ADDR sp)1639b725ae77Skettenis sh64_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
1640b725ae77Skettenis {
1641b725ae77Skettenis write_register (PR_REGNUM, entry_point_address ());
1642b725ae77Skettenis return sp;
1643b725ae77Skettenis }
1644b725ae77Skettenis
1645b725ae77Skettenis /* Find a function's return value in the appropriate registers (in
1646b725ae77Skettenis regbuf), and copy it into valbuf. Extract from an array REGBUF
1647b725ae77Skettenis containing the (raw) register state a function return value of type
1648b725ae77Skettenis TYPE, and copy that, in virtual format, into VALBUF. */
1649b725ae77Skettenis static void
sh64_extract_return_value(struct type * type,char * regbuf,char * valbuf)1650b725ae77Skettenis sh64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
1651b725ae77Skettenis {
1652b725ae77Skettenis int offset;
1653b725ae77Skettenis int return_register;
1654b725ae77Skettenis int len = TYPE_LENGTH (type);
1655b725ae77Skettenis
1656b725ae77Skettenis if (TYPE_CODE (type) == TYPE_CODE_FLT)
1657b725ae77Skettenis {
1658b725ae77Skettenis if (len == 4)
1659b725ae77Skettenis {
1660b725ae77Skettenis /* Return value stored in FP0_REGNUM */
1661b725ae77Skettenis return_register = FP0_REGNUM;
1662b725ae77Skettenis offset = DEPRECATED_REGISTER_BYTE (return_register);
1663b725ae77Skettenis memcpy (valbuf, (char *) regbuf + offset, len);
1664b725ae77Skettenis }
1665b725ae77Skettenis else if (len == 8)
1666b725ae77Skettenis {
1667b725ae77Skettenis /* return value stored in DR0_REGNUM */
1668b725ae77Skettenis DOUBLEST val;
1669b725ae77Skettenis
1670b725ae77Skettenis return_register = DR0_REGNUM;
1671b725ae77Skettenis offset = DEPRECATED_REGISTER_BYTE (return_register);
1672b725ae77Skettenis
1673b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
1674b725ae77Skettenis floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
1675b725ae77Skettenis (char *) regbuf + offset, &val);
1676b725ae77Skettenis else
1677b725ae77Skettenis floatformat_to_doublest (&floatformat_ieee_double_big,
1678b725ae77Skettenis (char *) regbuf + offset, &val);
1679b725ae77Skettenis store_typed_floating (valbuf, type, val);
1680b725ae77Skettenis }
1681b725ae77Skettenis }
1682b725ae77Skettenis else
1683b725ae77Skettenis {
1684b725ae77Skettenis if (len <= 8)
1685b725ae77Skettenis {
1686b725ae77Skettenis /* Result is in register 2. If smaller than 8 bytes, it is padded
1687b725ae77Skettenis at the most significant end. */
1688b725ae77Skettenis return_register = DEFAULT_RETURN_REGNUM;
1689b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
1690b725ae77Skettenis offset = DEPRECATED_REGISTER_BYTE (return_register) +
1691b725ae77Skettenis register_size (current_gdbarch, return_register) - len;
1692b725ae77Skettenis else
1693b725ae77Skettenis offset = DEPRECATED_REGISTER_BYTE (return_register);
1694b725ae77Skettenis memcpy (valbuf, (char *) regbuf + offset, len);
1695b725ae77Skettenis }
1696b725ae77Skettenis else
1697b725ae77Skettenis error ("bad size for return value");
1698b725ae77Skettenis }
1699b725ae77Skettenis }
1700b725ae77Skettenis
1701b725ae77Skettenis /* Write into appropriate registers a function return value
1702b725ae77Skettenis of type TYPE, given in virtual format.
1703b725ae77Skettenis If the architecture is sh4 or sh3e, store a function's return value
1704b725ae77Skettenis in the R0 general register or in the FP0 floating point register,
1705b725ae77Skettenis depending on the type of the return value. In all the other cases
1706b725ae77Skettenis the result is stored in r0, left-justified. */
1707b725ae77Skettenis
1708b725ae77Skettenis static void
sh64_store_return_value(struct type * type,char * valbuf)1709b725ae77Skettenis sh64_store_return_value (struct type *type, char *valbuf)
1710b725ae77Skettenis {
1711b725ae77Skettenis char buf[64]; /* more than enough... */
1712b725ae77Skettenis int len = TYPE_LENGTH (type);
1713b725ae77Skettenis
1714b725ae77Skettenis if (TYPE_CODE (type) == TYPE_CODE_FLT)
1715b725ae77Skettenis {
1716b725ae77Skettenis if (len == 4)
1717b725ae77Skettenis {
1718b725ae77Skettenis /* Return value stored in FP0_REGNUM */
1719b725ae77Skettenis deprecated_write_register_gen (FP0_REGNUM, valbuf);
1720b725ae77Skettenis }
1721b725ae77Skettenis if (len == 8)
1722b725ae77Skettenis {
1723b725ae77Skettenis /* return value stored in DR0_REGNUM */
1724b725ae77Skettenis /* FIXME: Implement */
1725b725ae77Skettenis }
1726b725ae77Skettenis }
1727b725ae77Skettenis else
1728b725ae77Skettenis {
1729b725ae77Skettenis int return_register = DEFAULT_RETURN_REGNUM;
1730b725ae77Skettenis int offset = 0;
1731b725ae77Skettenis
1732b725ae77Skettenis if (len <= register_size (current_gdbarch, return_register))
1733b725ae77Skettenis {
1734b725ae77Skettenis /* Pad with zeros. */
1735b725ae77Skettenis memset (buf, 0, register_size (current_gdbarch, return_register));
1736b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
1737b725ae77Skettenis offset = 0; /*register_size (current_gdbarch,
1738b725ae77Skettenis return_register) - len;*/
1739b725ae77Skettenis else
1740b725ae77Skettenis offset = register_size (current_gdbarch, return_register) - len;
1741b725ae77Skettenis
1742b725ae77Skettenis memcpy (buf + offset, valbuf, len);
1743b725ae77Skettenis deprecated_write_register_gen (return_register, buf);
1744b725ae77Skettenis }
1745b725ae77Skettenis else
1746b725ae77Skettenis deprecated_write_register_gen (return_register, valbuf);
1747b725ae77Skettenis }
1748b725ae77Skettenis }
1749b725ae77Skettenis
1750b725ae77Skettenis static void
sh64_show_media_regs(void)1751b725ae77Skettenis sh64_show_media_regs (void)
1752b725ae77Skettenis {
1753b725ae77Skettenis int i;
1754b725ae77Skettenis
1755b725ae77Skettenis printf_filtered ("PC=%s SR=%016llx \n",
1756b725ae77Skettenis paddr (read_register (PC_REGNUM)),
1757b725ae77Skettenis (long long) read_register (SR_REGNUM));
1758b725ae77Skettenis
1759b725ae77Skettenis printf_filtered ("SSR=%016llx SPC=%016llx \n",
1760b725ae77Skettenis (long long) read_register (SSR_REGNUM),
1761b725ae77Skettenis (long long) read_register (SPC_REGNUM));
1762b725ae77Skettenis printf_filtered ("FPSCR=%016lx\n ",
1763b725ae77Skettenis (long) read_register (FPSCR_REGNUM));
1764b725ae77Skettenis
1765b725ae77Skettenis for (i = 0; i < 64; i = i + 4)
1766b725ae77Skettenis printf_filtered ("\nR%d-R%d %016llx %016llx %016llx %016llx\n",
1767b725ae77Skettenis i, i + 3,
1768b725ae77Skettenis (long long) read_register (i + 0),
1769b725ae77Skettenis (long long) read_register (i + 1),
1770b725ae77Skettenis (long long) read_register (i + 2),
1771b725ae77Skettenis (long long) read_register (i + 3));
1772b725ae77Skettenis
1773b725ae77Skettenis printf_filtered ("\n");
1774b725ae77Skettenis
1775b725ae77Skettenis for (i = 0; i < 64; i = i + 8)
1776b725ae77Skettenis printf_filtered ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1777b725ae77Skettenis i, i + 7,
1778b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 0),
1779b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 1),
1780b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 2),
1781b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 3),
1782b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 4),
1783b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 5),
1784b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 6),
1785b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 7));
1786b725ae77Skettenis }
1787b725ae77Skettenis
1788b725ae77Skettenis static void
sh64_show_compact_regs(void)1789b725ae77Skettenis sh64_show_compact_regs (void)
1790b725ae77Skettenis {
1791b725ae77Skettenis int i;
1792b725ae77Skettenis
1793b725ae77Skettenis printf_filtered ("PC=%s \n",
1794b725ae77Skettenis paddr (read_register (PC_C_REGNUM)));
1795b725ae77Skettenis
1796b725ae77Skettenis printf_filtered ("GBR=%08lx MACH=%08lx MACL=%08lx PR=%08lx T=%08lx\n",
1797b725ae77Skettenis (long) read_register (GBR_C_REGNUM),
1798b725ae77Skettenis (long) read_register (MACH_C_REGNUM),
1799b725ae77Skettenis (long) read_register (MACL_C_REGNUM),
1800b725ae77Skettenis (long) read_register (PR_C_REGNUM),
1801b725ae77Skettenis (long) read_register (T_C_REGNUM));
1802b725ae77Skettenis printf_filtered ("FPSCR=%08lx FPUL=%08lx\n",
1803b725ae77Skettenis (long) read_register (FPSCR_C_REGNUM),
1804b725ae77Skettenis (long) read_register (FPUL_C_REGNUM));
1805b725ae77Skettenis
1806b725ae77Skettenis for (i = 0; i < 16; i = i + 4)
1807b725ae77Skettenis printf_filtered ("\nR%d-R%d %08lx %08lx %08lx %08lx\n",
1808b725ae77Skettenis i, i + 3,
1809b725ae77Skettenis (long) read_register (i + 0),
1810b725ae77Skettenis (long) read_register (i + 1),
1811b725ae77Skettenis (long) read_register (i + 2),
1812b725ae77Skettenis (long) read_register (i + 3));
1813b725ae77Skettenis
1814b725ae77Skettenis printf_filtered ("\n");
1815b725ae77Skettenis
1816b725ae77Skettenis for (i = 0; i < 16; i = i + 8)
1817b725ae77Skettenis printf_filtered ("FR%d-FR%d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
1818b725ae77Skettenis i, i + 7,
1819b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 0),
1820b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 1),
1821b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 2),
1822b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 3),
1823b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 4),
1824b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 5),
1825b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 6),
1826b725ae77Skettenis (long) read_register (FP0_REGNUM + i + 7));
1827b725ae77Skettenis }
1828b725ae77Skettenis
1829b725ae77Skettenis /* FIXME!!! This only shows the registers for shmedia, excluding the
1830b725ae77Skettenis pseudo registers. */
1831b725ae77Skettenis void
sh64_show_regs(void)1832b725ae77Skettenis sh64_show_regs (void)
1833b725ae77Skettenis {
1834b725ae77Skettenis if (deprecated_selected_frame
1835b725ae77Skettenis && pc_is_isa32 (get_frame_pc (deprecated_selected_frame)))
1836b725ae77Skettenis sh64_show_media_regs ();
1837b725ae77Skettenis else
1838b725ae77Skettenis sh64_show_compact_regs ();
1839b725ae77Skettenis }
1840b725ae77Skettenis
1841b725ae77Skettenis /* *INDENT-OFF* */
1842b725ae77Skettenis /*
1843b725ae77Skettenis SH MEDIA MODE (ISA 32)
1844b725ae77Skettenis general registers (64-bit) 0-63
1845b725ae77Skettenis 0 r0, r1, r2, r3, r4, r5, r6, r7,
1846b725ae77Skettenis 64 r8, r9, r10, r11, r12, r13, r14, r15,
1847b725ae77Skettenis 128 r16, r17, r18, r19, r20, r21, r22, r23,
1848b725ae77Skettenis 192 r24, r25, r26, r27, r28, r29, r30, r31,
1849b725ae77Skettenis 256 r32, r33, r34, r35, r36, r37, r38, r39,
1850b725ae77Skettenis 320 r40, r41, r42, r43, r44, r45, r46, r47,
1851b725ae77Skettenis 384 r48, r49, r50, r51, r52, r53, r54, r55,
1852b725ae77Skettenis 448 r56, r57, r58, r59, r60, r61, r62, r63,
1853b725ae77Skettenis
1854b725ae77Skettenis pc (64-bit) 64
1855b725ae77Skettenis 512 pc,
1856b725ae77Skettenis
1857b725ae77Skettenis status reg., saved status reg., saved pc reg. (64-bit) 65-67
1858b725ae77Skettenis 520 sr, ssr, spc,
1859b725ae77Skettenis
1860b725ae77Skettenis target registers (64-bit) 68-75
1861b725ae77Skettenis 544 tr0, tr1, tr2, tr3, tr4, tr5, tr6, tr7,
1862b725ae77Skettenis
1863b725ae77Skettenis floating point state control register (32-bit) 76
1864b725ae77Skettenis 608 fpscr,
1865b725ae77Skettenis
1866b725ae77Skettenis single precision floating point registers (32-bit) 77-140
1867b725ae77Skettenis 612 fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
1868b725ae77Skettenis 644 fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15,
1869b725ae77Skettenis 676 fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23,
1870b725ae77Skettenis 708 fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31,
1871b725ae77Skettenis 740 fr32, fr33, fr34, fr35, fr36, fr37, fr38, fr39,
1872b725ae77Skettenis 772 fr40, fr41, fr42, fr43, fr44, fr45, fr46, fr47,
1873b725ae77Skettenis 804 fr48, fr49, fr50, fr51, fr52, fr53, fr54, fr55,
1874b725ae77Skettenis 836 fr56, fr57, fr58, fr59, fr60, fr61, fr62, fr63,
1875b725ae77Skettenis
1876b725ae77Skettenis TOTAL SPACE FOR REGISTERS: 868 bytes
1877b725ae77Skettenis
1878b725ae77Skettenis From here on they are all pseudo registers: no memory allocated.
1879b725ae77Skettenis REGISTER_BYTE returns the register byte for the base register.
1880b725ae77Skettenis
1881b725ae77Skettenis double precision registers (pseudo) 141-172
1882b725ae77Skettenis dr0, dr2, dr4, dr6, dr8, dr10, dr12, dr14,
1883b725ae77Skettenis dr16, dr18, dr20, dr22, dr24, dr26, dr28, dr30,
1884b725ae77Skettenis dr32, dr34, dr36, dr38, dr40, dr42, dr44, dr46,
1885b725ae77Skettenis dr48, dr50, dr52, dr54, dr56, dr58, dr60, dr62,
1886b725ae77Skettenis
1887b725ae77Skettenis floating point pairs (pseudo) 173-204
1888b725ae77Skettenis fp0, fp2, fp4, fp6, fp8, fp10, fp12, fp14,
1889b725ae77Skettenis fp16, fp18, fp20, fp22, fp24, fp26, fp28, fp30,
1890b725ae77Skettenis fp32, fp34, fp36, fp38, fp40, fp42, fp44, fp46,
1891b725ae77Skettenis fp48, fp50, fp52, fp54, fp56, fp58, fp60, fp62,
1892b725ae77Skettenis
1893b725ae77Skettenis floating point vectors (4 floating point regs) (pseudo) 205-220
1894b725ae77Skettenis fv0, fv4, fv8, fv12, fv16, fv20, fv24, fv28,
1895b725ae77Skettenis fv32, fv36, fv40, fv44, fv48, fv52, fv56, fv60,
1896b725ae77Skettenis
1897b725ae77Skettenis SH COMPACT MODE (ISA 16) (all pseudo) 221-272
1898b725ae77Skettenis r0_c, r1_c, r2_c, r3_c, r4_c, r5_c, r6_c, r7_c,
1899b725ae77Skettenis r8_c, r9_c, r10_c, r11_c, r12_c, r13_c, r14_c, r15_c,
1900b725ae77Skettenis pc_c,
1901b725ae77Skettenis gbr_c, mach_c, macl_c, pr_c, t_c,
1902b725ae77Skettenis fpscr_c, fpul_c,
1903b725ae77Skettenis fr0_c, fr1_c, fr2_c, fr3_c, fr4_c, fr5_c, fr6_c, fr7_c,
1904b725ae77Skettenis fr8_c, fr9_c, fr10_c, fr11_c, fr12_c, fr13_c, fr14_c, fr15_c
1905b725ae77Skettenis dr0_c, dr2_c, dr4_c, dr6_c, dr8_c, dr10_c, dr12_c, dr14_c
1906b725ae77Skettenis fv0_c, fv4_c, fv8_c, fv12_c
1907b725ae77Skettenis */
1908b725ae77Skettenis /* *INDENT-ON* */
1909b725ae77Skettenis static int
sh64_register_byte(int reg_nr)1910b725ae77Skettenis sh64_register_byte (int reg_nr)
1911b725ae77Skettenis {
1912b725ae77Skettenis int base_regnum = -1;
1913b725ae77Skettenis
1914b725ae77Skettenis /* If it is a pseudo register, get the number of the first floating
1915b725ae77Skettenis point register that is part of it. */
1916b725ae77Skettenis if (reg_nr >= DR0_REGNUM
1917b725ae77Skettenis && reg_nr <= DR_LAST_REGNUM)
1918b725ae77Skettenis base_regnum = dr_reg_base_num (reg_nr);
1919b725ae77Skettenis
1920b725ae77Skettenis else if (reg_nr >= FPP0_REGNUM
1921b725ae77Skettenis && reg_nr <= FPP_LAST_REGNUM)
1922b725ae77Skettenis base_regnum = fpp_reg_base_num (reg_nr);
1923b725ae77Skettenis
1924b725ae77Skettenis else if (reg_nr >= FV0_REGNUM
1925b725ae77Skettenis && reg_nr <= FV_LAST_REGNUM)
1926b725ae77Skettenis base_regnum = fv_reg_base_num (reg_nr);
1927b725ae77Skettenis
1928b725ae77Skettenis /* sh compact pseudo register. FPSCR is a pathological case, need to
1929b725ae77Skettenis treat it as special. */
1930b725ae77Skettenis else if ((reg_nr >= R0_C_REGNUM
1931b725ae77Skettenis && reg_nr <= FV_LAST_C_REGNUM)
1932b725ae77Skettenis && reg_nr != FPSCR_C_REGNUM)
1933b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
1934b725ae77Skettenis
1935b725ae77Skettenis /* Now return the offset in bytes within the register cache. */
1936b725ae77Skettenis /* sh media pseudo register, i.e. any of DR, FFP, FV registers. */
1937b725ae77Skettenis if (reg_nr >= DR0_REGNUM
1938b725ae77Skettenis && reg_nr <= FV_LAST_REGNUM)
1939b725ae77Skettenis return (base_regnum - FP0_REGNUM + 1) * 4
1940b725ae77Skettenis + (TR7_REGNUM + 1) * 8;
1941b725ae77Skettenis
1942b725ae77Skettenis /* sh compact pseudo register: general register */
1943b725ae77Skettenis if ((reg_nr >= R0_C_REGNUM
1944b725ae77Skettenis && reg_nr <= R_LAST_C_REGNUM))
1945b725ae77Skettenis return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
1946b725ae77Skettenis ? base_regnum * 8 + 4
1947b725ae77Skettenis : base_regnum * 8);
1948b725ae77Skettenis
1949b725ae77Skettenis /* sh compact pseudo register: */
1950b725ae77Skettenis if (reg_nr == PC_C_REGNUM
1951b725ae77Skettenis || reg_nr == GBR_C_REGNUM
1952b725ae77Skettenis || reg_nr == MACL_C_REGNUM
1953b725ae77Skettenis || reg_nr == PR_C_REGNUM)
1954b725ae77Skettenis return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
1955b725ae77Skettenis ? base_regnum * 8 + 4
1956b725ae77Skettenis : base_regnum * 8);
1957b725ae77Skettenis
1958b725ae77Skettenis if (reg_nr == MACH_C_REGNUM)
1959b725ae77Skettenis return base_regnum * 8;
1960b725ae77Skettenis
1961b725ae77Skettenis if (reg_nr == T_C_REGNUM)
1962b725ae77Skettenis return base_regnum * 8; /* FIXME??? how do we get bit 0? Do we have to? */
1963b725ae77Skettenis
1964b725ae77Skettenis /* sh compact pseudo register: floating point register */
1965b725ae77Skettenis else if (reg_nr >= FP0_C_REGNUM
1966b725ae77Skettenis && reg_nr <= FV_LAST_C_REGNUM)
1967b725ae77Skettenis return (base_regnum - FP0_REGNUM) * 4
1968b725ae77Skettenis + (TR7_REGNUM + 1) * 8 + 4;
1969b725ae77Skettenis
1970b725ae77Skettenis else if (reg_nr == FPSCR_C_REGNUM)
1971b725ae77Skettenis /* This is complicated, for now return the beginning of the
1972b725ae77Skettenis architectural FPSCR register. */
1973b725ae77Skettenis return (TR7_REGNUM + 1) * 8;
1974b725ae77Skettenis
1975b725ae77Skettenis else if (reg_nr == FPUL_C_REGNUM)
1976b725ae77Skettenis return ((base_regnum - FP0_REGNUM) * 4 +
1977b725ae77Skettenis (TR7_REGNUM + 1) * 8 + 4);
1978b725ae77Skettenis
1979b725ae77Skettenis /* It is not a pseudo register. */
1980b725ae77Skettenis /* It is a 64 bit register. */
1981b725ae77Skettenis else if (reg_nr <= TR7_REGNUM)
1982b725ae77Skettenis return reg_nr * 8;
1983b725ae77Skettenis
1984b725ae77Skettenis /* It is a 32 bit register. */
1985b725ae77Skettenis else if (reg_nr == FPSCR_REGNUM)
1986b725ae77Skettenis return (FPSCR_REGNUM * 8);
1987b725ae77Skettenis
1988b725ae77Skettenis /* It is floating point 32-bit register */
1989b725ae77Skettenis else
1990b725ae77Skettenis return ((TR7_REGNUM + 1) * 8
1991b725ae77Skettenis + (reg_nr - FP0_REGNUM + 1) * 4);
1992b725ae77Skettenis }
1993b725ae77Skettenis
1994b725ae77Skettenis static struct type *
sh64_build_float_register_type(int high)1995b725ae77Skettenis sh64_build_float_register_type (int high)
1996b725ae77Skettenis {
1997b725ae77Skettenis struct type *temp;
1998b725ae77Skettenis
1999b725ae77Skettenis temp = create_range_type (NULL, builtin_type_int, 0, high);
2000b725ae77Skettenis return create_array_type (NULL, builtin_type_float, temp);
2001b725ae77Skettenis }
2002b725ae77Skettenis
2003b725ae77Skettenis /* Return the GDB type object for the "standard" data type
2004b725ae77Skettenis of data in register REG_NR. */
2005b725ae77Skettenis static struct type *
sh64_register_type(struct gdbarch * gdbarch,int reg_nr)2006b725ae77Skettenis sh64_register_type (struct gdbarch *gdbarch, int reg_nr)
2007b725ae77Skettenis {
2008b725ae77Skettenis if ((reg_nr >= FP0_REGNUM
2009b725ae77Skettenis && reg_nr <= FP_LAST_REGNUM)
2010b725ae77Skettenis || (reg_nr >= FP0_C_REGNUM
2011b725ae77Skettenis && reg_nr <= FP_LAST_C_REGNUM))
2012b725ae77Skettenis return builtin_type_float;
2013b725ae77Skettenis else if ((reg_nr >= DR0_REGNUM
2014b725ae77Skettenis && reg_nr <= DR_LAST_REGNUM)
2015b725ae77Skettenis || (reg_nr >= DR0_C_REGNUM
2016b725ae77Skettenis && reg_nr <= DR_LAST_C_REGNUM))
2017b725ae77Skettenis return builtin_type_double;
2018b725ae77Skettenis else if (reg_nr >= FPP0_REGNUM
2019b725ae77Skettenis && reg_nr <= FPP_LAST_REGNUM)
2020b725ae77Skettenis return sh64_build_float_register_type (1);
2021b725ae77Skettenis else if ((reg_nr >= FV0_REGNUM
2022b725ae77Skettenis && reg_nr <= FV_LAST_REGNUM)
2023b725ae77Skettenis ||(reg_nr >= FV0_C_REGNUM
2024b725ae77Skettenis && reg_nr <= FV_LAST_C_REGNUM))
2025b725ae77Skettenis return sh64_build_float_register_type (3);
2026b725ae77Skettenis else if (reg_nr == FPSCR_REGNUM)
2027b725ae77Skettenis return builtin_type_int;
2028b725ae77Skettenis else if (reg_nr >= R0_C_REGNUM
2029b725ae77Skettenis && reg_nr < FP0_C_REGNUM)
2030b725ae77Skettenis return builtin_type_int;
2031b725ae77Skettenis else
2032b725ae77Skettenis return builtin_type_long_long;
2033b725ae77Skettenis }
2034b725ae77Skettenis
2035b725ae77Skettenis static void
sh64_register_convert_to_virtual(int regnum,struct type * type,char * from,char * to)2036b725ae77Skettenis sh64_register_convert_to_virtual (int regnum, struct type *type,
2037b725ae77Skettenis char *from, char *to)
2038b725ae77Skettenis {
2039b725ae77Skettenis if (TARGET_BYTE_ORDER != BFD_ENDIAN_LITTLE)
2040b725ae77Skettenis {
2041b725ae77Skettenis /* It is a no-op. */
2042b725ae77Skettenis memcpy (to, from, register_size (current_gdbarch, regnum));
2043b725ae77Skettenis return;
2044b725ae77Skettenis }
2045b725ae77Skettenis
2046b725ae77Skettenis if ((regnum >= DR0_REGNUM
2047b725ae77Skettenis && regnum <= DR_LAST_REGNUM)
2048b725ae77Skettenis || (regnum >= DR0_C_REGNUM
2049b725ae77Skettenis && regnum <= DR_LAST_C_REGNUM))
2050b725ae77Skettenis {
2051b725ae77Skettenis DOUBLEST val;
2052b725ae77Skettenis floatformat_to_doublest (&floatformat_ieee_double_littlebyte_bigword,
2053b725ae77Skettenis from, &val);
2054b725ae77Skettenis store_typed_floating (to, type, val);
2055b725ae77Skettenis }
2056b725ae77Skettenis else
2057b725ae77Skettenis error ("sh64_register_convert_to_virtual called with non DR register number");
2058b725ae77Skettenis }
2059b725ae77Skettenis
2060b725ae77Skettenis static void
sh64_register_convert_to_raw(struct type * type,int regnum,const void * from,void * to)2061b725ae77Skettenis sh64_register_convert_to_raw (struct type *type, int regnum,
2062b725ae77Skettenis const void *from, void *to)
2063b725ae77Skettenis {
2064b725ae77Skettenis if (TARGET_BYTE_ORDER != BFD_ENDIAN_LITTLE)
2065b725ae77Skettenis {
2066b725ae77Skettenis /* It is a no-op. */
2067b725ae77Skettenis memcpy (to, from, register_size (current_gdbarch, regnum));
2068b725ae77Skettenis return;
2069b725ae77Skettenis }
2070b725ae77Skettenis
2071b725ae77Skettenis if ((regnum >= DR0_REGNUM
2072b725ae77Skettenis && regnum <= DR_LAST_REGNUM)
2073b725ae77Skettenis || (regnum >= DR0_C_REGNUM
2074b725ae77Skettenis && regnum <= DR_LAST_C_REGNUM))
2075b725ae77Skettenis {
2076b725ae77Skettenis DOUBLEST val = deprecated_extract_floating (from, TYPE_LENGTH(type));
2077b725ae77Skettenis floatformat_from_doublest (&floatformat_ieee_double_littlebyte_bigword,
2078b725ae77Skettenis &val, to);
2079b725ae77Skettenis }
2080b725ae77Skettenis else
2081b725ae77Skettenis error ("sh64_register_convert_to_raw called with non DR register number");
2082b725ae77Skettenis }
2083b725ae77Skettenis
2084b725ae77Skettenis static void
sh64_pseudo_register_read(struct gdbarch * gdbarch,struct regcache * regcache,int reg_nr,void * buffer)2085b725ae77Skettenis sh64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
2086b725ae77Skettenis int reg_nr, void *buffer)
2087b725ae77Skettenis {
2088b725ae77Skettenis int base_regnum;
2089b725ae77Skettenis int portion;
2090b725ae77Skettenis int offset = 0;
2091b725ae77Skettenis char temp_buffer[MAX_REGISTER_SIZE];
2092b725ae77Skettenis
2093b725ae77Skettenis if (reg_nr >= DR0_REGNUM
2094b725ae77Skettenis && reg_nr <= DR_LAST_REGNUM)
2095b725ae77Skettenis {
2096b725ae77Skettenis base_regnum = dr_reg_base_num (reg_nr);
2097b725ae77Skettenis
2098b725ae77Skettenis /* Build the value in the provided buffer. */
2099b725ae77Skettenis /* DR regs are double precision registers obtained by
2100b725ae77Skettenis concatenating 2 single precision floating point registers. */
2101b725ae77Skettenis for (portion = 0; portion < 2; portion++)
2102b725ae77Skettenis regcache_raw_read (regcache, base_regnum + portion,
2103b725ae77Skettenis (temp_buffer
2104b725ae77Skettenis + register_size (gdbarch, base_regnum) * portion));
2105b725ae77Skettenis
2106b725ae77Skettenis /* We must pay attention to the endianness. */
2107b725ae77Skettenis sh64_register_convert_to_virtual (reg_nr,
2108b725ae77Skettenis gdbarch_register_type (gdbarch,
2109b725ae77Skettenis reg_nr),
2110b725ae77Skettenis temp_buffer, buffer);
2111b725ae77Skettenis
2112b725ae77Skettenis }
2113b725ae77Skettenis
2114b725ae77Skettenis else if (reg_nr >= FPP0_REGNUM
2115b725ae77Skettenis && reg_nr <= FPP_LAST_REGNUM)
2116b725ae77Skettenis {
2117b725ae77Skettenis base_regnum = fpp_reg_base_num (reg_nr);
2118b725ae77Skettenis
2119b725ae77Skettenis /* Build the value in the provided buffer. */
2120b725ae77Skettenis /* FPP regs are pairs of single precision registers obtained by
2121b725ae77Skettenis concatenating 2 single precision floating point registers. */
2122b725ae77Skettenis for (portion = 0; portion < 2; portion++)
2123b725ae77Skettenis regcache_raw_read (regcache, base_regnum + portion,
2124b725ae77Skettenis ((char *) buffer
2125b725ae77Skettenis + register_size (gdbarch, base_regnum) * portion));
2126b725ae77Skettenis }
2127b725ae77Skettenis
2128b725ae77Skettenis else if (reg_nr >= FV0_REGNUM
2129b725ae77Skettenis && reg_nr <= FV_LAST_REGNUM)
2130b725ae77Skettenis {
2131b725ae77Skettenis base_regnum = fv_reg_base_num (reg_nr);
2132b725ae77Skettenis
2133b725ae77Skettenis /* Build the value in the provided buffer. */
2134b725ae77Skettenis /* FV regs are vectors of single precision registers obtained by
2135b725ae77Skettenis concatenating 4 single precision floating point registers. */
2136b725ae77Skettenis for (portion = 0; portion < 4; portion++)
2137b725ae77Skettenis regcache_raw_read (regcache, base_regnum + portion,
2138b725ae77Skettenis ((char *) buffer
2139b725ae77Skettenis + register_size (gdbarch, base_regnum) * portion));
2140b725ae77Skettenis }
2141b725ae77Skettenis
2142b725ae77Skettenis /* sh compact pseudo registers. 1-to-1 with a shmedia register */
2143b725ae77Skettenis else if (reg_nr >= R0_C_REGNUM
2144b725ae77Skettenis && reg_nr <= T_C_REGNUM)
2145b725ae77Skettenis {
2146b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2147b725ae77Skettenis
2148b725ae77Skettenis /* Build the value in the provided buffer. */
2149b725ae77Skettenis regcache_raw_read (regcache, base_regnum, temp_buffer);
2150b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
2151b725ae77Skettenis offset = 4;
2152b725ae77Skettenis memcpy (buffer, temp_buffer + offset, 4); /* get LOWER 32 bits only????*/
2153b725ae77Skettenis }
2154b725ae77Skettenis
2155b725ae77Skettenis else if (reg_nr >= FP0_C_REGNUM
2156b725ae77Skettenis && reg_nr <= FP_LAST_C_REGNUM)
2157b725ae77Skettenis {
2158b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2159b725ae77Skettenis
2160b725ae77Skettenis /* Build the value in the provided buffer. */
2161b725ae77Skettenis /* Floating point registers map 1-1 to the media fp regs,
2162b725ae77Skettenis they have the same size and endianness. */
2163b725ae77Skettenis regcache_raw_read (regcache, base_regnum, buffer);
2164b725ae77Skettenis }
2165b725ae77Skettenis
2166b725ae77Skettenis else if (reg_nr >= DR0_C_REGNUM
2167b725ae77Skettenis && reg_nr <= DR_LAST_C_REGNUM)
2168b725ae77Skettenis {
2169b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2170b725ae77Skettenis
2171b725ae77Skettenis /* DR_C regs are double precision registers obtained by
2172b725ae77Skettenis concatenating 2 single precision floating point registers. */
2173b725ae77Skettenis for (portion = 0; portion < 2; portion++)
2174b725ae77Skettenis regcache_raw_read (regcache, base_regnum + portion,
2175b725ae77Skettenis (temp_buffer
2176b725ae77Skettenis + register_size (gdbarch, base_regnum) * portion));
2177b725ae77Skettenis
2178b725ae77Skettenis /* We must pay attention to the endianness. */
2179b725ae77Skettenis sh64_register_convert_to_virtual (reg_nr,
2180b725ae77Skettenis gdbarch_register_type (gdbarch,
2181b725ae77Skettenis reg_nr),
2182b725ae77Skettenis temp_buffer, buffer);
2183b725ae77Skettenis }
2184b725ae77Skettenis
2185b725ae77Skettenis else if (reg_nr >= FV0_C_REGNUM
2186b725ae77Skettenis && reg_nr <= FV_LAST_C_REGNUM)
2187b725ae77Skettenis {
2188b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2189b725ae77Skettenis
2190b725ae77Skettenis /* Build the value in the provided buffer. */
2191b725ae77Skettenis /* FV_C regs are vectors of single precision registers obtained by
2192b725ae77Skettenis concatenating 4 single precision floating point registers. */
2193b725ae77Skettenis for (portion = 0; portion < 4; portion++)
2194b725ae77Skettenis regcache_raw_read (regcache, base_regnum + portion,
2195b725ae77Skettenis ((char *) buffer
2196b725ae77Skettenis + register_size (gdbarch, base_regnum) * portion));
2197b725ae77Skettenis }
2198b725ae77Skettenis
2199b725ae77Skettenis else if (reg_nr == FPSCR_C_REGNUM)
2200b725ae77Skettenis {
2201b725ae77Skettenis int fpscr_base_regnum;
2202b725ae77Skettenis int sr_base_regnum;
2203b725ae77Skettenis unsigned int fpscr_value;
2204b725ae77Skettenis unsigned int sr_value;
2205b725ae77Skettenis unsigned int fpscr_c_value;
2206b725ae77Skettenis unsigned int fpscr_c_part1_value;
2207b725ae77Skettenis unsigned int fpscr_c_part2_value;
2208b725ae77Skettenis
2209b725ae77Skettenis fpscr_base_regnum = FPSCR_REGNUM;
2210b725ae77Skettenis sr_base_regnum = SR_REGNUM;
2211b725ae77Skettenis
2212b725ae77Skettenis /* Build the value in the provided buffer. */
2213b725ae77Skettenis /* FPSCR_C is a very weird register that contains sparse bits
2214b725ae77Skettenis from the FPSCR and the SR architectural registers.
2215b725ae77Skettenis Specifically: */
2216b725ae77Skettenis /* *INDENT-OFF* */
2217b725ae77Skettenis /*
2218b725ae77Skettenis FPSRC_C bit
2219b725ae77Skettenis 0 Bit 0 of FPSCR
2220b725ae77Skettenis 1 reserved
2221b725ae77Skettenis 2-17 Bit 2-18 of FPSCR
2222b725ae77Skettenis 18-20 Bits 12,13,14 of SR
2223b725ae77Skettenis 21-31 reserved
2224b725ae77Skettenis */
2225b725ae77Skettenis /* *INDENT-ON* */
2226b725ae77Skettenis /* Get FPSCR into a local buffer */
2227b725ae77Skettenis regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
2228b725ae77Skettenis /* Get value as an int. */
2229b725ae77Skettenis fpscr_value = extract_unsigned_integer (temp_buffer, 4);
2230b725ae77Skettenis /* Get SR into a local buffer */
2231b725ae77Skettenis regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
2232b725ae77Skettenis /* Get value as an int. */
2233b725ae77Skettenis sr_value = extract_unsigned_integer (temp_buffer, 4);
2234b725ae77Skettenis /* Build the new value. */
2235b725ae77Skettenis fpscr_c_part1_value = fpscr_value & 0x3fffd;
2236b725ae77Skettenis fpscr_c_part2_value = (sr_value & 0x7000) << 6;
2237b725ae77Skettenis fpscr_c_value = fpscr_c_part1_value | fpscr_c_part2_value;
2238b725ae77Skettenis /* Store that in out buffer!!! */
2239b725ae77Skettenis store_unsigned_integer (buffer, 4, fpscr_c_value);
2240b725ae77Skettenis /* FIXME There is surely an endianness gotcha here. */
2241b725ae77Skettenis }
2242b725ae77Skettenis
2243b725ae77Skettenis else if (reg_nr == FPUL_C_REGNUM)
2244b725ae77Skettenis {
2245b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2246b725ae77Skettenis
2247b725ae77Skettenis /* FPUL_C register is floating point register 32,
2248b725ae77Skettenis same size, same endianness. */
2249b725ae77Skettenis regcache_raw_read (regcache, base_regnum, buffer);
2250b725ae77Skettenis }
2251b725ae77Skettenis }
2252b725ae77Skettenis
2253b725ae77Skettenis static void
sh64_pseudo_register_write(struct gdbarch * gdbarch,struct regcache * regcache,int reg_nr,const void * buffer)2254b725ae77Skettenis sh64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
2255b725ae77Skettenis int reg_nr, const void *buffer)
2256b725ae77Skettenis {
2257b725ae77Skettenis int base_regnum, portion;
2258b725ae77Skettenis int offset;
2259b725ae77Skettenis char temp_buffer[MAX_REGISTER_SIZE];
2260b725ae77Skettenis
2261b725ae77Skettenis if (reg_nr >= DR0_REGNUM
2262b725ae77Skettenis && reg_nr <= DR_LAST_REGNUM)
2263b725ae77Skettenis {
2264b725ae77Skettenis base_regnum = dr_reg_base_num (reg_nr);
2265b725ae77Skettenis /* We must pay attention to the endianness. */
2266b725ae77Skettenis sh64_register_convert_to_raw (gdbarch_register_type (gdbarch, reg_nr),
2267b725ae77Skettenis reg_nr,
2268b725ae77Skettenis buffer, temp_buffer);
2269b725ae77Skettenis
2270b725ae77Skettenis /* Write the real regs for which this one is an alias. */
2271b725ae77Skettenis for (portion = 0; portion < 2; portion++)
2272b725ae77Skettenis regcache_raw_write (regcache, base_regnum + portion,
2273b725ae77Skettenis (temp_buffer
2274b725ae77Skettenis + register_size (gdbarch,
2275b725ae77Skettenis base_regnum) * portion));
2276b725ae77Skettenis }
2277b725ae77Skettenis
2278b725ae77Skettenis else if (reg_nr >= FPP0_REGNUM
2279b725ae77Skettenis && reg_nr <= FPP_LAST_REGNUM)
2280b725ae77Skettenis {
2281b725ae77Skettenis base_regnum = fpp_reg_base_num (reg_nr);
2282b725ae77Skettenis
2283b725ae77Skettenis /* Write the real regs for which this one is an alias. */
2284b725ae77Skettenis for (portion = 0; portion < 2; portion++)
2285b725ae77Skettenis regcache_raw_write (regcache, base_regnum + portion,
2286b725ae77Skettenis ((char *) buffer
2287b725ae77Skettenis + register_size (gdbarch,
2288b725ae77Skettenis base_regnum) * portion));
2289b725ae77Skettenis }
2290b725ae77Skettenis
2291b725ae77Skettenis else if (reg_nr >= FV0_REGNUM
2292b725ae77Skettenis && reg_nr <= FV_LAST_REGNUM)
2293b725ae77Skettenis {
2294b725ae77Skettenis base_regnum = fv_reg_base_num (reg_nr);
2295b725ae77Skettenis
2296b725ae77Skettenis /* Write the real regs for which this one is an alias. */
2297b725ae77Skettenis for (portion = 0; portion < 4; portion++)
2298b725ae77Skettenis regcache_raw_write (regcache, base_regnum + portion,
2299b725ae77Skettenis ((char *) buffer
2300b725ae77Skettenis + register_size (gdbarch,
2301b725ae77Skettenis base_regnum) * portion));
2302b725ae77Skettenis }
2303b725ae77Skettenis
2304b725ae77Skettenis /* sh compact general pseudo registers. 1-to-1 with a shmedia
2305b725ae77Skettenis register but only 4 bytes of it. */
2306b725ae77Skettenis else if (reg_nr >= R0_C_REGNUM
2307b725ae77Skettenis && reg_nr <= T_C_REGNUM)
2308b725ae77Skettenis {
2309b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2310b725ae77Skettenis /* reg_nr is 32 bit here, and base_regnum is 64 bits. */
2311b725ae77Skettenis if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
2312b725ae77Skettenis offset = 4;
2313b725ae77Skettenis else
2314b725ae77Skettenis offset = 0;
2315b725ae77Skettenis /* Let's read the value of the base register into a temporary
2316b725ae77Skettenis buffer, so that overwriting the last four bytes with the new
2317b725ae77Skettenis value of the pseudo will leave the upper 4 bytes unchanged. */
2318b725ae77Skettenis regcache_raw_read (regcache, base_regnum, temp_buffer);
2319b725ae77Skettenis /* Write as an 8 byte quantity */
2320b725ae77Skettenis memcpy (temp_buffer + offset, buffer, 4);
2321b725ae77Skettenis regcache_raw_write (regcache, base_regnum, temp_buffer);
2322b725ae77Skettenis }
2323b725ae77Skettenis
2324b725ae77Skettenis /* sh floating point compact pseudo registers. 1-to-1 with a shmedia
2325b725ae77Skettenis registers. Both are 4 bytes. */
2326b725ae77Skettenis else if (reg_nr >= FP0_C_REGNUM
2327b725ae77Skettenis && reg_nr <= FP_LAST_C_REGNUM)
2328b725ae77Skettenis {
2329b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2330b725ae77Skettenis regcache_raw_write (regcache, base_regnum, buffer);
2331b725ae77Skettenis }
2332b725ae77Skettenis
2333b725ae77Skettenis else if (reg_nr >= DR0_C_REGNUM
2334b725ae77Skettenis && reg_nr <= DR_LAST_C_REGNUM)
2335b725ae77Skettenis {
2336b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2337b725ae77Skettenis for (portion = 0; portion < 2; portion++)
2338b725ae77Skettenis {
2339b725ae77Skettenis /* We must pay attention to the endianness. */
2340b725ae77Skettenis sh64_register_convert_to_raw (gdbarch_register_type (gdbarch,
2341b725ae77Skettenis reg_nr),
2342b725ae77Skettenis reg_nr,
2343b725ae77Skettenis buffer, temp_buffer);
2344b725ae77Skettenis
2345b725ae77Skettenis regcache_raw_write (regcache, base_regnum + portion,
2346b725ae77Skettenis (temp_buffer
2347b725ae77Skettenis + register_size (gdbarch,
2348b725ae77Skettenis base_regnum) * portion));
2349b725ae77Skettenis }
2350b725ae77Skettenis }
2351b725ae77Skettenis
2352b725ae77Skettenis else if (reg_nr >= FV0_C_REGNUM
2353b725ae77Skettenis && reg_nr <= FV_LAST_C_REGNUM)
2354b725ae77Skettenis {
2355b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2356b725ae77Skettenis
2357b725ae77Skettenis for (portion = 0; portion < 4; portion++)
2358b725ae77Skettenis {
2359b725ae77Skettenis regcache_raw_write (regcache, base_regnum + portion,
2360b725ae77Skettenis ((char *) buffer
2361b725ae77Skettenis + register_size (gdbarch,
2362b725ae77Skettenis base_regnum) * portion));
2363b725ae77Skettenis }
2364b725ae77Skettenis }
2365b725ae77Skettenis
2366b725ae77Skettenis else if (reg_nr == FPSCR_C_REGNUM)
2367b725ae77Skettenis {
2368b725ae77Skettenis int fpscr_base_regnum;
2369b725ae77Skettenis int sr_base_regnum;
2370b725ae77Skettenis unsigned int fpscr_value;
2371b725ae77Skettenis unsigned int sr_value;
2372b725ae77Skettenis unsigned int old_fpscr_value;
2373b725ae77Skettenis unsigned int old_sr_value;
2374b725ae77Skettenis unsigned int fpscr_c_value;
2375b725ae77Skettenis unsigned int fpscr_mask;
2376b725ae77Skettenis unsigned int sr_mask;
2377b725ae77Skettenis
2378b725ae77Skettenis fpscr_base_regnum = FPSCR_REGNUM;
2379b725ae77Skettenis sr_base_regnum = SR_REGNUM;
2380b725ae77Skettenis
2381b725ae77Skettenis /* FPSCR_C is a very weird register that contains sparse bits
2382b725ae77Skettenis from the FPSCR and the SR architectural registers.
2383b725ae77Skettenis Specifically: */
2384b725ae77Skettenis /* *INDENT-OFF* */
2385b725ae77Skettenis /*
2386b725ae77Skettenis FPSRC_C bit
2387b725ae77Skettenis 0 Bit 0 of FPSCR
2388b725ae77Skettenis 1 reserved
2389b725ae77Skettenis 2-17 Bit 2-18 of FPSCR
2390b725ae77Skettenis 18-20 Bits 12,13,14 of SR
2391b725ae77Skettenis 21-31 reserved
2392b725ae77Skettenis */
2393b725ae77Skettenis /* *INDENT-ON* */
2394b725ae77Skettenis /* Get value as an int. */
2395b725ae77Skettenis fpscr_c_value = extract_unsigned_integer (buffer, 4);
2396b725ae77Skettenis
2397b725ae77Skettenis /* Build the new values. */
2398b725ae77Skettenis fpscr_mask = 0x0003fffd;
2399b725ae77Skettenis sr_mask = 0x001c0000;
2400b725ae77Skettenis
2401b725ae77Skettenis fpscr_value = fpscr_c_value & fpscr_mask;
2402b725ae77Skettenis sr_value = (fpscr_value & sr_mask) >> 6;
2403b725ae77Skettenis
2404b725ae77Skettenis regcache_raw_read (regcache, fpscr_base_regnum, temp_buffer);
2405b725ae77Skettenis old_fpscr_value = extract_unsigned_integer (temp_buffer, 4);
2406b725ae77Skettenis old_fpscr_value &= 0xfffc0002;
2407b725ae77Skettenis fpscr_value |= old_fpscr_value;
2408b725ae77Skettenis store_unsigned_integer (temp_buffer, 4, fpscr_value);
2409b725ae77Skettenis regcache_raw_write (regcache, fpscr_base_regnum, temp_buffer);
2410b725ae77Skettenis
2411b725ae77Skettenis regcache_raw_read (regcache, sr_base_regnum, temp_buffer);
2412b725ae77Skettenis old_sr_value = extract_unsigned_integer (temp_buffer, 4);
2413b725ae77Skettenis old_sr_value &= 0xffff8fff;
2414b725ae77Skettenis sr_value |= old_sr_value;
2415b725ae77Skettenis store_unsigned_integer (temp_buffer, 4, sr_value);
2416b725ae77Skettenis regcache_raw_write (regcache, sr_base_regnum, temp_buffer);
2417b725ae77Skettenis }
2418b725ae77Skettenis
2419b725ae77Skettenis else if (reg_nr == FPUL_C_REGNUM)
2420b725ae77Skettenis {
2421b725ae77Skettenis base_regnum = sh64_compact_reg_base_num (reg_nr);
2422b725ae77Skettenis regcache_raw_write (regcache, base_regnum, buffer);
2423b725ae77Skettenis }
2424b725ae77Skettenis }
2425b725ae77Skettenis
2426b725ae77Skettenis /* Floating point vector of 4 float registers. */
2427b725ae77Skettenis static void
do_fv_register_info(struct gdbarch * gdbarch,struct ui_file * file,int fv_regnum)2428b725ae77Skettenis do_fv_register_info (struct gdbarch *gdbarch, struct ui_file *file,
2429b725ae77Skettenis int fv_regnum)
2430b725ae77Skettenis {
2431b725ae77Skettenis int first_fp_reg_num = fv_reg_base_num (fv_regnum);
2432b725ae77Skettenis fprintf_filtered (file, "fv%d\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
2433b725ae77Skettenis fv_regnum - FV0_REGNUM,
2434b725ae77Skettenis (int) read_register (first_fp_reg_num),
2435b725ae77Skettenis (int) read_register (first_fp_reg_num + 1),
2436b725ae77Skettenis (int) read_register (first_fp_reg_num + 2),
2437b725ae77Skettenis (int) read_register (first_fp_reg_num + 3));
2438b725ae77Skettenis }
2439b725ae77Skettenis
2440b725ae77Skettenis /* Floating point vector of 4 float registers, compact mode. */
2441b725ae77Skettenis static void
do_fv_c_register_info(int fv_regnum)2442b725ae77Skettenis do_fv_c_register_info (int fv_regnum)
2443b725ae77Skettenis {
2444b725ae77Skettenis int first_fp_reg_num = sh64_compact_reg_base_num (fv_regnum);
2445b725ae77Skettenis printf_filtered ("fv%d_c\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
2446b725ae77Skettenis fv_regnum - FV0_C_REGNUM,
2447b725ae77Skettenis (int) read_register (first_fp_reg_num),
2448b725ae77Skettenis (int) read_register (first_fp_reg_num + 1),
2449b725ae77Skettenis (int) read_register (first_fp_reg_num + 2),
2450b725ae77Skettenis (int) read_register (first_fp_reg_num + 3));
2451b725ae77Skettenis }
2452b725ae77Skettenis
2453b725ae77Skettenis /* Pairs of single regs. The DR are instead double precision
2454b725ae77Skettenis registers. */
2455b725ae77Skettenis static void
do_fpp_register_info(int fpp_regnum)2456b725ae77Skettenis do_fpp_register_info (int fpp_regnum)
2457b725ae77Skettenis {
2458b725ae77Skettenis int first_fp_reg_num = fpp_reg_base_num (fpp_regnum);
2459b725ae77Skettenis
2460b725ae77Skettenis printf_filtered ("fpp%d\t0x%08x\t0x%08x\n",
2461b725ae77Skettenis fpp_regnum - FPP0_REGNUM,
2462b725ae77Skettenis (int) read_register (first_fp_reg_num),
2463b725ae77Skettenis (int) read_register (first_fp_reg_num + 1));
2464b725ae77Skettenis }
2465b725ae77Skettenis
2466b725ae77Skettenis /* Double precision registers. */
2467b725ae77Skettenis static void
do_dr_register_info(struct gdbarch * gdbarch,struct ui_file * file,int dr_regnum)2468b725ae77Skettenis do_dr_register_info (struct gdbarch *gdbarch, struct ui_file *file,
2469b725ae77Skettenis int dr_regnum)
2470b725ae77Skettenis {
2471b725ae77Skettenis int first_fp_reg_num = dr_reg_base_num (dr_regnum);
2472b725ae77Skettenis
2473b725ae77Skettenis fprintf_filtered (file, "dr%d\t0x%08x%08x\n",
2474b725ae77Skettenis dr_regnum - DR0_REGNUM,
2475b725ae77Skettenis (int) read_register (first_fp_reg_num),
2476b725ae77Skettenis (int) read_register (first_fp_reg_num + 1));
2477b725ae77Skettenis }
2478b725ae77Skettenis
2479b725ae77Skettenis /* Double precision registers, compact mode. */
2480b725ae77Skettenis static void
do_dr_c_register_info(int dr_regnum)2481b725ae77Skettenis do_dr_c_register_info (int dr_regnum)
2482b725ae77Skettenis {
2483b725ae77Skettenis int first_fp_reg_num = sh64_compact_reg_base_num (dr_regnum);
2484b725ae77Skettenis
2485b725ae77Skettenis printf_filtered ("dr%d_c\t0x%08x%08x\n",
2486b725ae77Skettenis dr_regnum - DR0_C_REGNUM,
2487b725ae77Skettenis (int) read_register (first_fp_reg_num),
2488b725ae77Skettenis (int) read_register (first_fp_reg_num +1));
2489b725ae77Skettenis }
2490b725ae77Skettenis
2491b725ae77Skettenis /* General register in compact mode. */
2492b725ae77Skettenis static void
do_r_c_register_info(int r_c_regnum)2493b725ae77Skettenis do_r_c_register_info (int r_c_regnum)
2494b725ae77Skettenis {
2495b725ae77Skettenis int regnum = sh64_compact_reg_base_num (r_c_regnum);
2496b725ae77Skettenis
2497b725ae77Skettenis printf_filtered ("r%d_c\t0x%08x\n",
2498b725ae77Skettenis r_c_regnum - R0_C_REGNUM,
2499b725ae77Skettenis /*FIXME!!!*/ (int) read_register (regnum));
2500b725ae77Skettenis }
2501b725ae77Skettenis
2502b725ae77Skettenis /* FIXME:!! THIS SHOULD TAKE CARE OF GETTING THE RIGHT PORTION OF THE
2503b725ae77Skettenis shmedia REGISTERS. */
2504b725ae77Skettenis /* Control registers, compact mode. */
2505b725ae77Skettenis static void
do_cr_c_register_info(int cr_c_regnum)2506b725ae77Skettenis do_cr_c_register_info (int cr_c_regnum)
2507b725ae77Skettenis {
2508b725ae77Skettenis switch (cr_c_regnum)
2509b725ae77Skettenis {
2510b725ae77Skettenis case 237: printf_filtered ("pc_c\t0x%08x\n", (int) read_register (cr_c_regnum));
2511b725ae77Skettenis break;
2512b725ae77Skettenis case 238: printf_filtered ("gbr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
2513b725ae77Skettenis break;
2514b725ae77Skettenis case 239: printf_filtered ("mach_c\t0x%08x\n", (int) read_register (cr_c_regnum));
2515b725ae77Skettenis break;
2516b725ae77Skettenis case 240: printf_filtered ("macl_c\t0x%08x\n", (int) read_register (cr_c_regnum));
2517b725ae77Skettenis break;
2518b725ae77Skettenis case 241: printf_filtered ("pr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
2519b725ae77Skettenis break;
2520b725ae77Skettenis case 242: printf_filtered ("t_c\t0x%08x\n", (int) read_register (cr_c_regnum));
2521b725ae77Skettenis break;
2522b725ae77Skettenis case 243: printf_filtered ("fpscr_c\t0x%08x\n", (int) read_register (cr_c_regnum));
2523b725ae77Skettenis break;
2524b725ae77Skettenis case 244: printf_filtered ("fpul_c\t0x%08x\n", (int)read_register (cr_c_regnum));
2525b725ae77Skettenis break;
2526b725ae77Skettenis }
2527b725ae77Skettenis }
2528b725ae77Skettenis
2529b725ae77Skettenis static void
sh_do_fp_register(struct gdbarch * gdbarch,struct ui_file * file,int regnum)2530b725ae77Skettenis sh_do_fp_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
2531b725ae77Skettenis { /* do values for FP (float) regs */
2532b725ae77Skettenis char *raw_buffer;
2533b725ae77Skettenis double flt; /* double extracted from raw hex data */
2534b725ae77Skettenis int inv;
2535b725ae77Skettenis int j;
2536b725ae77Skettenis
2537b725ae77Skettenis /* Allocate space for the float. */
2538b725ae77Skettenis raw_buffer = (char *) alloca (register_size (gdbarch, FP0_REGNUM));
2539b725ae77Skettenis
2540b725ae77Skettenis /* Get the data in raw format. */
2541b725ae77Skettenis if (!frame_register_read (get_selected_frame (), regnum, raw_buffer))
2542b725ae77Skettenis error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
2543b725ae77Skettenis
2544b725ae77Skettenis /* Get the register as a number */
2545b725ae77Skettenis flt = unpack_double (builtin_type_float, raw_buffer, &inv);
2546b725ae77Skettenis
2547b725ae77Skettenis /* Print the name and some spaces. */
2548b725ae77Skettenis fputs_filtered (REGISTER_NAME (regnum), file);
2549b725ae77Skettenis print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
2550b725ae77Skettenis
2551b725ae77Skettenis /* Print the value. */
2552b725ae77Skettenis if (inv)
2553b725ae77Skettenis fprintf_filtered (file, "<invalid float>");
2554b725ae77Skettenis else
2555b725ae77Skettenis fprintf_filtered (file, "%-10.9g", flt);
2556b725ae77Skettenis
2557b725ae77Skettenis /* Print the fp register as hex. */
2558b725ae77Skettenis fprintf_filtered (file, "\t(raw 0x");
2559b725ae77Skettenis for (j = 0; j < register_size (gdbarch, regnum); j++)
2560b725ae77Skettenis {
2561b725ae77Skettenis int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j
2562b725ae77Skettenis : register_size (gdbarch, regnum) - 1 - j;
2563b725ae77Skettenis fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[idx]);
2564b725ae77Skettenis }
2565b725ae77Skettenis fprintf_filtered (file, ")");
2566b725ae77Skettenis fprintf_filtered (file, "\n");
2567b725ae77Skettenis }
2568b725ae77Skettenis
2569b725ae77Skettenis static void
sh64_do_pseudo_register(int regnum)2570b725ae77Skettenis sh64_do_pseudo_register (int regnum)
2571b725ae77Skettenis {
2572b725ae77Skettenis /* All the sh64-compact mode registers are pseudo registers. */
2573b725ae77Skettenis
2574b725ae77Skettenis if (regnum < NUM_REGS
2575b725ae77Skettenis || regnum >= NUM_REGS + NUM_PSEUDO_REGS_SH_MEDIA + NUM_PSEUDO_REGS_SH_COMPACT)
2576b725ae77Skettenis internal_error (__FILE__, __LINE__,
2577b725ae77Skettenis "Invalid pseudo register number %d\n", regnum);
2578b725ae77Skettenis
2579b725ae77Skettenis else if ((regnum >= DR0_REGNUM
2580b725ae77Skettenis && regnum <= DR_LAST_REGNUM))
2581b725ae77Skettenis do_dr_register_info (current_gdbarch, gdb_stdout, regnum);
2582b725ae77Skettenis
2583b725ae77Skettenis else if ((regnum >= DR0_C_REGNUM
2584b725ae77Skettenis && regnum <= DR_LAST_C_REGNUM))
2585b725ae77Skettenis do_dr_c_register_info (regnum);
2586b725ae77Skettenis
2587b725ae77Skettenis else if ((regnum >= FV0_REGNUM
2588b725ae77Skettenis && regnum <= FV_LAST_REGNUM))
2589b725ae77Skettenis do_fv_register_info (current_gdbarch, gdb_stdout, regnum);
2590b725ae77Skettenis
2591b725ae77Skettenis else if ((regnum >= FV0_C_REGNUM
2592b725ae77Skettenis && regnum <= FV_LAST_C_REGNUM))
2593b725ae77Skettenis do_fv_c_register_info (regnum);
2594b725ae77Skettenis
2595b725ae77Skettenis else if (regnum >= FPP0_REGNUM
2596b725ae77Skettenis && regnum <= FPP_LAST_REGNUM)
2597b725ae77Skettenis do_fpp_register_info (regnum);
2598b725ae77Skettenis
2599b725ae77Skettenis else if (regnum >= R0_C_REGNUM
2600b725ae77Skettenis && regnum <= R_LAST_C_REGNUM)
2601b725ae77Skettenis /* FIXME, this function will not print the right format. */
2602b725ae77Skettenis do_r_c_register_info (regnum);
2603b725ae77Skettenis else if (regnum >= FP0_C_REGNUM
2604b725ae77Skettenis && regnum <= FP_LAST_C_REGNUM)
2605b725ae77Skettenis /* This should work also for pseudoregs. */
2606b725ae77Skettenis sh_do_fp_register (current_gdbarch, gdb_stdout, regnum);
2607b725ae77Skettenis else if (regnum >= PC_C_REGNUM
2608b725ae77Skettenis && regnum <= FPUL_C_REGNUM)
2609b725ae77Skettenis do_cr_c_register_info (regnum);
2610b725ae77Skettenis }
2611b725ae77Skettenis
2612b725ae77Skettenis static void
sh_do_register(struct gdbarch * gdbarch,struct ui_file * file,int regnum)2613b725ae77Skettenis sh_do_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
2614b725ae77Skettenis {
2615b725ae77Skettenis char raw_buffer[MAX_REGISTER_SIZE];
2616b725ae77Skettenis
2617b725ae77Skettenis fputs_filtered (REGISTER_NAME (regnum), file);
2618b725ae77Skettenis print_spaces_filtered (15 - strlen (REGISTER_NAME (regnum)), file);
2619b725ae77Skettenis
2620b725ae77Skettenis /* Get the data in raw format. */
2621b725ae77Skettenis if (!frame_register_read (get_selected_frame (), regnum, raw_buffer))
2622b725ae77Skettenis fprintf_filtered (file, "*value not available*\n");
2623b725ae77Skettenis
2624b725ae77Skettenis val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
2625b725ae77Skettenis file, 'x', 1, 0, Val_pretty_default);
2626b725ae77Skettenis fprintf_filtered (file, "\t");
2627b725ae77Skettenis val_print (gdbarch_register_type (gdbarch, regnum), raw_buffer, 0, 0,
2628b725ae77Skettenis file, 0, 1, 0, Val_pretty_default);
2629b725ae77Skettenis fprintf_filtered (file, "\n");
2630b725ae77Skettenis }
2631b725ae77Skettenis
2632b725ae77Skettenis static void
sh_print_register(struct gdbarch * gdbarch,struct ui_file * file,int regnum)2633b725ae77Skettenis sh_print_register (struct gdbarch *gdbarch, struct ui_file *file, int regnum)
2634b725ae77Skettenis {
2635b725ae77Skettenis if (regnum < 0 || regnum >= NUM_REGS + NUM_PSEUDO_REGS)
2636b725ae77Skettenis internal_error (__FILE__, __LINE__,
2637b725ae77Skettenis "Invalid register number %d\n", regnum);
2638b725ae77Skettenis
2639b725ae77Skettenis else if (regnum >= 0 && regnum < NUM_REGS)
2640b725ae77Skettenis {
2641b725ae77Skettenis if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
2642b725ae77Skettenis sh_do_fp_register (gdbarch, file, regnum); /* FP regs */
2643b725ae77Skettenis else
2644b725ae77Skettenis sh_do_register (gdbarch, file, regnum); /* All other regs */
2645b725ae77Skettenis }
2646b725ae77Skettenis
2647b725ae77Skettenis else if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
2648b725ae77Skettenis sh64_do_pseudo_register (regnum);
2649b725ae77Skettenis }
2650b725ae77Skettenis
2651b725ae77Skettenis static void
sh_print_registers_info(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,int regnum,int fpregs)2652b725ae77Skettenis sh_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
2653b725ae77Skettenis struct frame_info *frame, int regnum, int fpregs)
2654b725ae77Skettenis {
2655b725ae77Skettenis if (regnum != -1) /* do one specified register */
2656b725ae77Skettenis {
2657b725ae77Skettenis if (*(REGISTER_NAME (regnum)) == '\0')
2658b725ae77Skettenis error ("Not a valid register for the current processor type");
2659b725ae77Skettenis
2660b725ae77Skettenis sh_print_register (gdbarch, file, regnum);
2661b725ae77Skettenis }
2662b725ae77Skettenis else
2663b725ae77Skettenis /* do all (or most) registers */
2664b725ae77Skettenis {
2665b725ae77Skettenis regnum = 0;
2666b725ae77Skettenis while (regnum < NUM_REGS)
2667b725ae77Skettenis {
2668b725ae77Skettenis /* If the register name is empty, it is undefined for this
2669b725ae77Skettenis processor, so don't display anything. */
2670b725ae77Skettenis if (REGISTER_NAME (regnum) == NULL
2671b725ae77Skettenis || *(REGISTER_NAME (regnum)) == '\0')
2672b725ae77Skettenis {
2673b725ae77Skettenis regnum++;
2674b725ae77Skettenis continue;
2675b725ae77Skettenis }
2676b725ae77Skettenis
2677b725ae77Skettenis if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
2678b725ae77Skettenis {
2679b725ae77Skettenis if (fpregs)
2680b725ae77Skettenis {
2681b725ae77Skettenis /* true for "INFO ALL-REGISTERS" command */
2682b725ae77Skettenis sh_do_fp_register (gdbarch, file, regnum); /* FP regs */
2683b725ae77Skettenis regnum ++;
2684b725ae77Skettenis }
2685b725ae77Skettenis else
2686b725ae77Skettenis regnum += FP_LAST_REGNUM - FP0_REGNUM; /* skip FP regs */
2687b725ae77Skettenis }
2688b725ae77Skettenis else
2689b725ae77Skettenis {
2690b725ae77Skettenis sh_do_register (gdbarch, file, regnum); /* All other regs */
2691b725ae77Skettenis regnum++;
2692b725ae77Skettenis }
2693b725ae77Skettenis }
2694b725ae77Skettenis
2695b725ae77Skettenis if (fpregs)
2696b725ae77Skettenis while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
2697b725ae77Skettenis {
2698b725ae77Skettenis sh64_do_pseudo_register (regnum);
2699b725ae77Skettenis regnum++;
2700b725ae77Skettenis }
2701b725ae77Skettenis }
2702b725ae77Skettenis }
2703b725ae77Skettenis
2704b725ae77Skettenis static void
sh_compact_do_registers_info(int regnum,int fpregs)2705b725ae77Skettenis sh_compact_do_registers_info (int regnum, int fpregs)
2706b725ae77Skettenis {
2707b725ae77Skettenis if (regnum != -1) /* do one specified register */
2708b725ae77Skettenis {
2709b725ae77Skettenis if (*(REGISTER_NAME (regnum)) == '\0')
2710b725ae77Skettenis error ("Not a valid register for the current processor type");
2711b725ae77Skettenis
2712b725ae77Skettenis if (regnum >= 0 && regnum < R0_C_REGNUM)
2713b725ae77Skettenis error ("Not a valid register for the current processor mode.");
2714b725ae77Skettenis
2715b725ae77Skettenis sh_print_register (current_gdbarch, gdb_stdout, regnum);
2716b725ae77Skettenis }
2717b725ae77Skettenis else
2718b725ae77Skettenis /* do all compact registers */
2719b725ae77Skettenis {
2720b725ae77Skettenis regnum = R0_C_REGNUM;
2721b725ae77Skettenis while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
2722b725ae77Skettenis {
2723b725ae77Skettenis sh64_do_pseudo_register (regnum);
2724b725ae77Skettenis regnum++;
2725b725ae77Skettenis }
2726b725ae77Skettenis }
2727b725ae77Skettenis }
2728b725ae77Skettenis
2729b725ae77Skettenis static void
sh64_do_registers_info(int regnum,int fpregs)2730b725ae77Skettenis sh64_do_registers_info (int regnum, int fpregs)
2731b725ae77Skettenis {
2732b725ae77Skettenis if (pc_is_isa32 (get_frame_pc (deprecated_selected_frame)))
2733b725ae77Skettenis sh_print_registers_info (current_gdbarch, gdb_stdout,
2734b725ae77Skettenis deprecated_selected_frame, regnum, fpregs);
2735b725ae77Skettenis else
2736b725ae77Skettenis sh_compact_do_registers_info (regnum, fpregs);
2737b725ae77Skettenis }
2738b725ae77Skettenis
2739b725ae77Skettenis /* Fetch (and possibly build) an appropriate link_map_offsets structure
2740b725ae77Skettenis for native i386 linux targets using the struct offsets defined in
2741b725ae77Skettenis link.h (but without actual reference to that file).
2742b725ae77Skettenis
2743b725ae77Skettenis This makes it possible to access i386-linux shared libraries from
2744b725ae77Skettenis a gdb that was not built on an i386-linux host (for cross debugging).
2745b725ae77Skettenis */
2746b725ae77Skettenis
2747b725ae77Skettenis struct link_map_offsets *
sh_linux_svr4_fetch_link_map_offsets(void)2748b725ae77Skettenis sh_linux_svr4_fetch_link_map_offsets (void)
2749b725ae77Skettenis {
2750b725ae77Skettenis static struct link_map_offsets lmo;
2751b725ae77Skettenis static struct link_map_offsets *lmp = 0;
2752b725ae77Skettenis
2753b725ae77Skettenis if (lmp == 0)
2754b725ae77Skettenis {
2755b725ae77Skettenis lmp = &lmo;
2756b725ae77Skettenis
2757b725ae77Skettenis lmo.r_debug_size = 8; /* 20 not actual size but all we need */
2758b725ae77Skettenis
2759b725ae77Skettenis lmo.r_map_offset = 4;
2760b725ae77Skettenis lmo.r_map_size = 4;
2761b725ae77Skettenis
2762b725ae77Skettenis lmo.link_map_size = 20; /* 552 not actual size but all we need */
2763b725ae77Skettenis
2764b725ae77Skettenis lmo.l_addr_offset = 0;
2765b725ae77Skettenis lmo.l_addr_size = 4;
2766b725ae77Skettenis
2767b725ae77Skettenis lmo.l_name_offset = 4;
2768b725ae77Skettenis lmo.l_name_size = 4;
2769b725ae77Skettenis
2770b725ae77Skettenis lmo.l_next_offset = 12;
2771b725ae77Skettenis lmo.l_next_size = 4;
2772b725ae77Skettenis
2773b725ae77Skettenis lmo.l_prev_offset = 16;
2774b725ae77Skettenis lmo.l_prev_size = 4;
2775b725ae77Skettenis }
2776b725ae77Skettenis
2777b725ae77Skettenis return lmp;
2778b725ae77Skettenis }
2779b725ae77Skettenis
2780b725ae77Skettenis gdbarch_init_ftype sh64_gdbarch_init;
2781b725ae77Skettenis
2782b725ae77Skettenis struct gdbarch *
sh64_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)2783b725ae77Skettenis sh64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
2784b725ae77Skettenis {
2785b725ae77Skettenis struct gdbarch *gdbarch;
2786b725ae77Skettenis struct gdbarch_tdep *tdep;
2787b725ae77Skettenis
2788b725ae77Skettenis /* If there is already a candidate, use it. */
2789b725ae77Skettenis arches = gdbarch_list_lookup_by_info (arches, &info);
2790b725ae77Skettenis if (arches != NULL)
2791b725ae77Skettenis return arches->gdbarch;
2792b725ae77Skettenis
2793b725ae77Skettenis /* None found, create a new architecture from the information
2794b725ae77Skettenis provided. */
2795b725ae77Skettenis tdep = XMALLOC (struct gdbarch_tdep);
2796b725ae77Skettenis gdbarch = gdbarch_alloc (&info, tdep);
2797b725ae77Skettenis
2798b725ae77Skettenis /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
2799b725ae77Skettenis ready to unwind the PC first (see frame.c:get_prev_frame()). */
2800b725ae77Skettenis set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
2801b725ae77Skettenis
2802b725ae77Skettenis /* Determine the ABI */
2803b725ae77Skettenis if (info.abfd && bfd_get_arch_size (info.abfd) == 64)
2804b725ae77Skettenis {
2805b725ae77Skettenis /* If the ABI is the 64-bit one, it can only be sh-media. */
2806b725ae77Skettenis tdep->sh_abi = SH_ABI_64;
2807b725ae77Skettenis set_gdbarch_ptr_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2808b725ae77Skettenis set_gdbarch_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2809b725ae77Skettenis }
2810b725ae77Skettenis else
2811b725ae77Skettenis {
2812b725ae77Skettenis /* If the ABI is the 32-bit one it could be either media or
2813b725ae77Skettenis compact. */
2814b725ae77Skettenis tdep->sh_abi = SH_ABI_32;
2815b725ae77Skettenis set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2816b725ae77Skettenis set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2817b725ae77Skettenis }
2818b725ae77Skettenis
2819b725ae77Skettenis set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
2820b725ae77Skettenis set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2821b725ae77Skettenis set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2822b725ae77Skettenis set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
2823b725ae77Skettenis set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2824b725ae77Skettenis set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
2825b725ae77Skettenis
2826b725ae77Skettenis set_gdbarch_sp_regnum (gdbarch, 15);
2827b725ae77Skettenis set_gdbarch_deprecated_fp_regnum (gdbarch, 14);
2828b725ae77Skettenis
2829b725ae77Skettenis set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh);
2830b725ae77Skettenis set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno);
2831b725ae77Skettenis
2832b725ae77Skettenis set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
2833b725ae77Skettenis
2834b725ae77Skettenis set_gdbarch_skip_prologue (gdbarch, sh_skip_prologue);
2835b725ae77Skettenis set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
2836b725ae77Skettenis
2837b725ae77Skettenis set_gdbarch_believe_pcc_promotion (gdbarch, 1);
2838b725ae77Skettenis
2839b725ae77Skettenis set_gdbarch_deprecated_frame_saved_pc (gdbarch, sh_frame_saved_pc);
2840b725ae77Skettenis set_gdbarch_deprecated_saved_pc_after_call (gdbarch, sh_saved_pc_after_call);
2841b725ae77Skettenis set_gdbarch_frame_align (gdbarch, sh_frame_align);
2842b725ae77Skettenis
2843b725ae77Skettenis set_gdbarch_num_pseudo_regs (gdbarch, NUM_PSEUDO_REGS_SH_MEDIA + NUM_PSEUDO_REGS_SH_COMPACT);
2844b725ae77Skettenis set_gdbarch_fp0_regnum (gdbarch, SIM_SH64_FR0_REGNUM);
2845b725ae77Skettenis set_gdbarch_pc_regnum (gdbarch, 64);
2846b725ae77Skettenis
2847b725ae77Skettenis /* The number of real registers is the same whether we are in
2848b725ae77Skettenis ISA16(compact) or ISA32(media). */
2849b725ae77Skettenis set_gdbarch_num_regs (gdbarch, SIM_SH64_NR_REGS);
2850b725ae77Skettenis
2851b725ae77Skettenis set_gdbarch_register_name (gdbarch, sh64_register_name);
2852b725ae77Skettenis set_gdbarch_register_type (gdbarch, sh64_register_type);
2853b725ae77Skettenis set_gdbarch_deprecated_store_return_value (gdbarch, sh64_store_return_value);
2854b725ae77Skettenis set_gdbarch_deprecated_register_byte (gdbarch, sh64_register_byte);
2855b725ae77Skettenis set_gdbarch_pseudo_register_read (gdbarch, sh64_pseudo_register_read);
2856b725ae77Skettenis set_gdbarch_pseudo_register_write (gdbarch, sh64_pseudo_register_write);
2857b725ae77Skettenis
2858b725ae77Skettenis set_gdbarch_deprecated_do_registers_info (gdbarch, sh64_do_registers_info);
2859b725ae77Skettenis set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, sh64_nofp_frame_init_saved_regs);
2860b725ae77Skettenis set_gdbarch_breakpoint_from_pc (gdbarch, sh64_breakpoint_from_pc);
2861b725ae77Skettenis
2862b725ae77Skettenis set_gdbarch_deprecated_init_extra_frame_info (gdbarch, sh64_init_extra_frame_info);
2863b725ae77Skettenis set_gdbarch_deprecated_frame_chain (gdbarch, sh64_frame_chain);
2864b725ae77Skettenis set_gdbarch_deprecated_get_saved_register (gdbarch, sh64_get_saved_register);
2865b725ae77Skettenis set_gdbarch_deprecated_extract_return_value (gdbarch, sh64_extract_return_value);
2866b725ae77Skettenis set_gdbarch_deprecated_push_arguments (gdbarch, sh64_push_arguments);
2867b725ae77Skettenis set_gdbarch_deprecated_push_return_address (gdbarch, sh64_push_return_address);
2868b725ae77Skettenis set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
2869b725ae77Skettenis set_gdbarch_deprecated_store_struct_return (gdbarch, sh64_store_struct_return);
2870b725ae77Skettenis set_gdbarch_deprecated_extract_struct_value_address (gdbarch, sh64_extract_struct_value_address);
2871*11efff7fSkettenis set_gdbarch_deprecated_use_struct_convention (gdbarch, sh64_use_struct_convention);
2872b725ae77Skettenis set_gdbarch_deprecated_pop_frame (gdbarch, sh64_pop_frame);
2873b725ae77Skettenis set_gdbarch_elf_make_msymbol_special (gdbarch,
2874b725ae77Skettenis sh64_elf_make_msymbol_special);
2875b725ae77Skettenis
2876b725ae77Skettenis /* Hook in ABI-specific overrides, if they have been registered. */
2877b725ae77Skettenis gdbarch_init_osabi (info, gdbarch);
2878b725ae77Skettenis
2879b725ae77Skettenis return gdbarch;
2880b725ae77Skettenis }
2881