Commit | Line | Data |
---|---|---|
8b39fe56 MK |
1 | /* Target-dependent code for FreeBSD/sparc64. |
2 | ||
3 | Copyright 2003 Free Software Foundation, Inc. | |
4 | ||
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
19 | Foundation, Inc., 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. */ | |
21 | ||
22 | #include "defs.h" | |
23 | #include "gdbcore.h" | |
24 | #include "osabi.h" | |
25 | #include "regcache.h" | |
26 | #include "target.h" | |
27 | ||
28 | #include "gdb_string.h" | |
29 | ||
30 | #include "sparc64-tdep.h" | |
31 | ||
32 | /* From <machine/reg.h>. */ | |
33 | ||
34 | /* Offset of registers in `struct reg'. */ | |
35 | int sparc64fbsd_r_global_offset = (0 * 8); | |
36 | int sparc64fbsd_r_out_offset = (8 * 8); | |
37 | int sparc64fbsd_r_fprs_offset = (16 * 8); | |
38 | int sparc64fbsd_r_tnpc_offset = (24 * 8); | |
39 | int sparc64fbsd_r_tpc_offset = (25 * 8); | |
40 | int sparc64fbsd_r_tstate_offset = (26 * 8); | |
41 | int sparc64fbsd_r_y_offset = (28 * 8); | |
42 | ||
43 | /* Size of `struct reg' and `struct fpreg'. */ | |
44 | int sparc64fbsd_sizeof_struct_reg = 256; | |
45 | int sparc64fbsd_sizeof_struct_fpreg = 272; | |
46 | ||
47 | void | |
48 | sparc64fbsd_supply_reg (const char *regs, int regnum) | |
49 | { | |
50 | char buf[8]; | |
51 | int i; | |
52 | ||
53 | if (regnum == SPARC64_PC_REGNUM || regnum == -1) | |
54 | supply_register (SPARC64_PC_REGNUM, regs + sparc64fbsd_r_tpc_offset); | |
55 | ||
56 | if (regnum == SPARC64_NPC_REGNUM || regnum == -1) | |
57 | supply_register (SPARC64_NPC_REGNUM, regs + sparc64fbsd_r_tnpc_offset); | |
58 | ||
59 | if (regnum == SPARC64_STATE_REGNUM || regnum == -1) | |
60 | supply_register (SPARC64_STATE_REGNUM, regs + sparc64fbsd_r_tstate_offset); | |
61 | ||
62 | if (regnum == SPARC64_FPRS_REGNUM || regnum == -1) | |
63 | supply_register (SPARC64_FPRS_REGNUM, regs + sparc64fbsd_r_fprs_offset); | |
64 | ||
65 | if (regnum == SPARC64_Y_REGNUM || regnum == -1) | |
66 | supply_register (SPARC64_Y_REGNUM, regs + sparc64fbsd_r_y_offset); | |
67 | ||
68 | if ((regnum >= SPARC_G0_REGNUM && regnum <= SPARC_G7_REGNUM) || regnum == -1) | |
69 | { | |
70 | if (regnum == SPARC_G0_REGNUM || regnum == -1) | |
71 | supply_register (SPARC_G0_REGNUM, NULL); /* %g0 is always zero. */ | |
72 | for (i = SPARC_G1_REGNUM; i <= SPARC_G7_REGNUM; i++) | |
73 | { | |
74 | if (regnum == i || regnum == -1) | |
75 | supply_register (i, (regs + sparc64fbsd_r_global_offset | |
76 | + ((i - SPARC_G0_REGNUM) * 8))); | |
77 | } | |
78 | } | |
79 | ||
80 | if ((regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) | |
81 | { | |
82 | for (i = SPARC_O0_REGNUM; i <= SPARC_O7_REGNUM; i++) | |
83 | { | |
84 | if (regnum == i || regnum == -1) | |
85 | supply_register (i, (regs + sparc64fbsd_r_out_offset | |
86 | + ((i - SPARC_O0_REGNUM) * 8))); | |
87 | } | |
88 | } | |
89 | ||
90 | /* Inputs and Locals are stored onto the stack by by the kernel. */ | |
91 | if ((regnum >= SPARC_L0_REGNUM && regnum <= SPARC_I7_REGNUM) || regnum == -1) | |
92 | { | |
93 | ULONGEST sp; | |
94 | ||
95 | regcache_cooked_read_unsigned (current_regcache, SPARC_SP_REGNUM, &sp); | |
3567a8ea | 96 | sparc_supply_rwindow (sp, regnum); |
8b39fe56 MK |
97 | } |
98 | } | |
99 | ||
100 | void | |
101 | sparc64fbsd_fill_reg (char *regs, int regnum) | |
102 | { | |
103 | char buf[8]; | |
104 | int i; | |
105 | ||
106 | if (regnum == SPARC64_PC_REGNUM || regnum == -1) | |
107 | regcache_collect (SPARC64_PC_REGNUM, regs + sparc64fbsd_r_tpc_offset); | |
108 | ||
109 | if (regnum == SPARC64_NPC_REGNUM || regnum == -1) | |
110 | regcache_collect (SPARC64_NPC_REGNUM, regs + sparc64fbsd_r_tnpc_offset); | |
111 | ||
112 | if (regnum == SPARC64_FPRS_REGNUM || regnum == -1) | |
113 | regcache_collect (SPARC64_FPRS_REGNUM, regs + sparc64fbsd_r_fprs_offset); | |
114 | ||
115 | if (regnum == SPARC64_Y_REGNUM || regnum == -1) | |
116 | regcache_collect (SPARC64_Y_REGNUM, regs + sparc64fbsd_r_y_offset); | |
117 | ||
118 | if ((regnum >= SPARC_G0_REGNUM && regnum <= SPARC_G7_REGNUM) || regnum == -1) | |
119 | { | |
120 | /* %g0 is always zero. */ | |
121 | for (i = SPARC_G1_REGNUM; i <= SPARC_G7_REGNUM; i++) | |
122 | { | |
123 | if (regnum == i || regnum == -1) | |
124 | regcache_collect (i, (regs + sparc64fbsd_r_global_offset | |
125 | + ((i - SPARC_G0_REGNUM) * 8))); | |
126 | } | |
127 | } | |
128 | ||
129 | if ((regnum >= SPARC_O0_REGNUM && regnum <= SPARC_O7_REGNUM) || regnum == -1) | |
130 | { | |
131 | for (i = SPARC_O0_REGNUM; i <= SPARC_O7_REGNUM; i++) | |
132 | { | |
133 | if (regnum == i || regnum == -1) | |
134 | regcache_collect (i, (regs + sparc64fbsd_r_out_offset | |
135 | + ((i - SPARC_O0_REGNUM) * 8))); | |
136 | } | |
137 | } | |
138 | ||
139 | /* Responsibility for the stack regs is pushed off onto the caller. */ | |
140 | } | |
141 | ||
142 | void | |
143 | sparc64fbsd_supply_fpreg (const char *fpregs, int regnum) | |
144 | { | |
145 | int i; | |
146 | ||
147 | for (i = 0; i < 32; i++) | |
148 | { | |
149 | if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) | |
150 | supply_register (SPARC_F0_REGNUM + i, fpregs + (i * 4)); | |
151 | } | |
152 | ||
153 | for (i = 0; i < 16; i++) | |
154 | { | |
155 | if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1) | |
156 | supply_register (SPARC64_F32_REGNUM + i, fpregs + (32 * 4) + (i * 8)); | |
157 | } | |
158 | ||
159 | if (regnum == SPARC64_FSR_REGNUM || regnum == -1) | |
160 | supply_register (SPARC64_FSR_REGNUM, fpregs + (32 * 4) + (16 * 8)); | |
161 | } | |
162 | ||
163 | void | |
164 | sparc64fbsd_fill_fpreg (char *fpregs, int regnum) | |
165 | { | |
166 | int i; | |
167 | ||
168 | for (i = 0; i < 32; i++) | |
169 | { | |
170 | if (regnum == (SPARC_F0_REGNUM + i) || regnum == -1) | |
171 | regcache_collect (SPARC_F0_REGNUM + i, fpregs + (i * 4)); | |
172 | } | |
173 | ||
174 | for (i = 0; i < 16; i++) | |
175 | { | |
176 | if (regnum == (SPARC64_F32_REGNUM + i) || regnum == -1) | |
177 | regcache_collect (SPARC64_F32_REGNUM + i, fpregs + (32 * 4) + (i * 8)); | |
178 | } | |
179 | ||
180 | if (regnum == SPARC64_FSR_REGNUM || regnum == -1) | |
181 | regcache_collect (SPARC64_FSR_REGNUM, fpregs + (32 * 4) + (16 * 8)); | |
182 | } | |
183 | \f | |
184 | ||
185 | static void | |
186 | fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, | |
187 | CORE_ADDR ignore) | |
188 | { | |
189 | switch (which) | |
190 | { | |
191 | case 0: /* Integer registers */ | |
192 | if (core_reg_size != sparc64fbsd_sizeof_struct_reg) | |
193 | warning ("Wrong size register set in core file."); | |
194 | else | |
195 | sparc64fbsd_supply_reg (core_reg_sect, -1); | |
196 | break; | |
197 | ||
198 | case 2: /* Floating pointer registers */ | |
199 | if (core_reg_size != sparc64fbsd_sizeof_struct_fpreg) | |
200 | warning ("Wrong size FP register set in core file."); | |
201 | else | |
202 | sparc64fbsd_supply_fpreg (core_reg_sect, -1); | |
203 | break; | |
204 | ||
205 | default: | |
206 | /* Don't know what kind of register request this is; just ignore it. */ | |
207 | break; | |
208 | } | |
209 | } | |
210 | ||
211 | static struct core_fns sparc64fbsd_core_fns = | |
212 | { | |
213 | bfd_target_elf_flavour, /* core_flavour */ | |
214 | default_check_format, /* check_format */ | |
215 | default_core_sniffer, /* core_sniffer */ | |
216 | fetch_core_registers, /* core_read_registers */ | |
217 | NULL | |
218 | }; | |
219 | \f | |
220 | ||
221 | static void | |
222 | sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |
223 | { | |
224 | /* Nothing yet. */ | |
225 | } | |
226 | ||
227 | /* Provide a prototype to silence -Wmissing-prototypes. */ | |
228 | void _initialize_sparc64fbsd_tdep (void); | |
229 | ||
230 | void | |
231 | _initialize_sparc64fbsd_tdep (void) | |
232 | { | |
233 | gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9, | |
234 | GDB_OSABI_FREEBSD_ELF, sparc64fbsd_init_abi); | |
235 | ||
236 | add_core_fns (&sparc64fbsd_core_fns); | |
237 | } |