Checkin gdb.arch/i386-avx.exp.
[deliverable/binutils-gdb.git] / gdb / gdbserver / i387-fp.c
CommitLineData
58caa3dc 1/* i387-specific utility functions, for the remote server for GDB.
4c38e0a4 2 Copyright (C) 2000, 2001, 2002, 2005, 2007, 2008, 2009, 2010
9b254dd1 3 Free Software Foundation, Inc.
58caa3dc
DJ
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
58caa3dc
DJ
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
58caa3dc
DJ
19
20#include "server.h"
0d62e5e8 21#include "i387-fp.h"
58caa3dc
DJ
22
23int num_xmm_registers = 8;
24
25/* Note: These functions preserve the reserved bits in control registers.
26 However, gdbserver promptly throws away that information. */
27
28/* These structs should have the proper sizes and alignment on both
29 i386 and x86-64 machines. */
30
31struct i387_fsave {
32 /* All these are only sixteen bits, plus padding, except for fop (which
33 is only eleven bits), and fooff / fioff (which are 32 bits each). */
0c2ead7e
DJ
34 unsigned short fctrl;
35 unsigned short pad1;
36 unsigned short fstat;
37 unsigned short pad2;
38 unsigned short ftag;
39 unsigned short pad3;
58caa3dc
DJ
40 unsigned int fioff;
41 unsigned short fiseg;
42 unsigned short fop;
43 unsigned int fooff;
0c2ead7e
DJ
44 unsigned short foseg;
45 unsigned short pad4;
58caa3dc
DJ
46
47 /* Space for eight 80-bit FP values. */
f450004a 48 unsigned char st_space[80];
58caa3dc
DJ
49};
50
51struct i387_fxsave {
52 /* All these are only sixteen bits, plus padding, except for fop (which
53 is only eleven bits), and fooff / fioff (which are 32 bits each). */
54 unsigned short fctrl;
55 unsigned short fstat;
56 unsigned short ftag;
57 unsigned short fop;
58 unsigned int fioff;
0c2ead7e
DJ
59 unsigned short fiseg;
60 unsigned short pad1;
58caa3dc 61 unsigned int fooff;
0c2ead7e
DJ
62 unsigned short foseg;
63 unsigned short pad12;
58caa3dc
DJ
64
65 unsigned int mxcsr;
0c2ead7e 66 unsigned int pad3;
58caa3dc
DJ
67
68 /* Space for eight 80-bit FP values in 128-bit spaces. */
f450004a 69 unsigned char st_space[128];
58caa3dc
DJ
70
71 /* Space for eight 128-bit XMM values, or 16 on x86-64. */
f450004a 72 unsigned char xmm_space[256];
58caa3dc
DJ
73};
74
75void
442ea881 76i387_cache_to_fsave (struct regcache *regcache, void *buf)
58caa3dc
DJ
77{
78 struct i387_fsave *fp = (struct i387_fsave *) buf;
79 int i;
80 int st0_regnum = find_regno ("st0");
81 unsigned long val, val2;
82
83 for (i = 0; i < 8; i++)
442ea881
PA
84 collect_register (regcache, i + st0_regnum,
85 ((char *) &fp->st_space[0]) + i * 10);
58caa3dc 86
442ea881
PA
87 collect_register_by_name (regcache, "fioff", &fp->fioff);
88 collect_register_by_name (regcache, "fooff", &fp->fooff);
58caa3dc
DJ
89
90 /* This one's 11 bits... */
442ea881 91 collect_register_by_name (regcache, "fop", &val2);
58caa3dc
DJ
92 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
93
94 /* Some registers are 16-bit. */
442ea881 95 collect_register_by_name (regcache, "fctrl", &val);
0c2ead7e 96 fp->fctrl = val;
58caa3dc 97
442ea881 98 collect_register_by_name (regcache, "fstat", &val);
58caa3dc 99 val &= 0xFFFF;
0c2ead7e 100 fp->fstat = val;
58caa3dc 101
442ea881 102 collect_register_by_name (regcache, "ftag", &val);
58caa3dc 103 val &= 0xFFFF;
0c2ead7e 104 fp->ftag = val;
58caa3dc 105
442ea881 106 collect_register_by_name (regcache, "fiseg", &val);
58caa3dc 107 val &= 0xFFFF;
0c2ead7e 108 fp->fiseg = val;
58caa3dc 109
442ea881 110 collect_register_by_name (regcache, "foseg", &val);
58caa3dc 111 val &= 0xFFFF;
0c2ead7e 112 fp->foseg = val;
58caa3dc
DJ
113}
114
115void
442ea881 116i387_fsave_to_cache (struct regcache *regcache, const void *buf)
58caa3dc
DJ
117{
118 struct i387_fsave *fp = (struct i387_fsave *) buf;
119 int i;
120 int st0_regnum = find_regno ("st0");
121 unsigned long val;
122
123 for (i = 0; i < 8; i++)
442ea881
PA
124 supply_register (regcache, i + st0_regnum,
125 ((char *) &fp->st_space[0]) + i * 10);
58caa3dc 126
442ea881
PA
127 supply_register_by_name (regcache, "fioff", &fp->fioff);
128 supply_register_by_name (regcache, "fooff", &fp->fooff);
1b3f6016 129
58caa3dc
DJ
130 /* Some registers are 16-bit. */
131 val = fp->fctrl & 0xFFFF;
442ea881 132 supply_register_by_name (regcache, "fctrl", &val);
58caa3dc
DJ
133
134 val = fp->fstat & 0xFFFF;
442ea881 135 supply_register_by_name (regcache, "fstat", &val);
58caa3dc
DJ
136
137 val = fp->ftag & 0xFFFF;
442ea881 138 supply_register_by_name (regcache, "ftag", &val);
58caa3dc
DJ
139
140 val = fp->fiseg & 0xFFFF;
442ea881 141 supply_register_by_name (regcache, "fiseg", &val);
58caa3dc
DJ
142
143 val = fp->foseg & 0xFFFF;
442ea881 144 supply_register_by_name (regcache, "foseg", &val);
58caa3dc 145
0c2ead7e 146 /* fop has only 11 valid bits. */
58caa3dc 147 val = (fp->fop) & 0x7FF;
442ea881 148 supply_register_by_name (regcache, "fop", &val);
58caa3dc
DJ
149}
150
151void
442ea881 152i387_cache_to_fxsave (struct regcache *regcache, void *buf)
58caa3dc
DJ
153{
154 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
155 int i;
156 int st0_regnum = find_regno ("st0");
157 int xmm0_regnum = find_regno ("xmm0");
158 unsigned long val, val2;
159
160 for (i = 0; i < 8; i++)
442ea881
PA
161 collect_register (regcache, i + st0_regnum,
162 ((char *) &fp->st_space[0]) + i * 16);
58caa3dc 163 for (i = 0; i < num_xmm_registers; i++)
442ea881
PA
164 collect_register (regcache, i + xmm0_regnum,
165 ((char *) &fp->xmm_space[0]) + i * 16);
58caa3dc 166
442ea881
PA
167 collect_register_by_name (regcache, "fioff", &fp->fioff);
168 collect_register_by_name (regcache, "fooff", &fp->fooff);
169 collect_register_by_name (regcache, "mxcsr", &fp->mxcsr);
1b3f6016 170
58caa3dc 171 /* This one's 11 bits... */
442ea881 172 collect_register_by_name (regcache, "fop", &val2);
58caa3dc
DJ
173 fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
174
175 /* Some registers are 16-bit. */
442ea881 176 collect_register_by_name (regcache, "fctrl", &val);
0c2ead7e 177 fp->fctrl = val;
58caa3dc 178
442ea881 179 collect_register_by_name (regcache, "fstat", &val);
0c2ead7e 180 fp->fstat = val;
58caa3dc
DJ
181
182 /* Convert to the simplifed tag form stored in fxsave data. */
442ea881 183 collect_register_by_name (regcache, "ftag", &val);
58caa3dc 184 val &= 0xFFFF;
73725ff3 185 val2 = 0;
58caa3dc
DJ
186 for (i = 7; i >= 0; i--)
187 {
188 int tag = (val >> (i * 2)) & 3;
189
190 if (tag != 3)
191 val2 |= (1 << i);
192 }
0c2ead7e 193 fp->ftag = val2;
58caa3dc 194
442ea881 195 collect_register_by_name (regcache, "fiseg", &val);
0c2ead7e 196 fp->fiseg = val;
58caa3dc 197
442ea881 198 collect_register_by_name (regcache, "foseg", &val);
0c2ead7e 199 fp->foseg = val;
58caa3dc
DJ
200}
201
202static int
203i387_ftag (struct i387_fxsave *fp, int regno)
204{
205 unsigned char *raw = &fp->st_space[regno * 16];
206 unsigned int exponent;
207 unsigned long fraction[2];
208 int integer;
209
210 integer = raw[7] & 0x80;
211 exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
212 fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
213 fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
1b3f6016 214 | (raw[5] << 8) | raw[4]);
58caa3dc
DJ
215
216 if (exponent == 0x7fff)
217 {
218 /* Special. */
219 return (2);
220 }
221 else if (exponent == 0x0000)
222 {
223 if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
1b3f6016
PA
224 {
225 /* Zero. */
226 return (1);
227 }
58caa3dc 228 else
1b3f6016
PA
229 {
230 /* Special. */
231 return (2);
232 }
58caa3dc
DJ
233 }
234 else
235 {
236 if (integer)
1b3f6016
PA
237 {
238 /* Valid. */
239 return (0);
240 }
58caa3dc 241 else
1b3f6016
PA
242 {
243 /* Special. */
244 return (2);
245 }
58caa3dc
DJ
246 }
247}
248
249void
442ea881 250i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
58caa3dc
DJ
251{
252 struct i387_fxsave *fp = (struct i387_fxsave *) buf;
253 int i, top;
254 int st0_regnum = find_regno ("st0");
255 int xmm0_regnum = find_regno ("xmm0");
256 unsigned long val;
257
258 for (i = 0; i < 8; i++)
442ea881
PA
259 supply_register (regcache, i + st0_regnum,
260 ((char *) &fp->st_space[0]) + i * 16);
58caa3dc 261 for (i = 0; i < num_xmm_registers; i++)
442ea881
PA
262 supply_register (regcache, i + xmm0_regnum,
263 ((char *) &fp->xmm_space[0]) + i * 16);
58caa3dc 264
442ea881
PA
265 supply_register_by_name (regcache, "fioff", &fp->fioff);
266 supply_register_by_name (regcache, "fooff", &fp->fooff);
267 supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
1b3f6016 268
58caa3dc
DJ
269 /* Some registers are 16-bit. */
270 val = fp->fctrl & 0xFFFF;
442ea881 271 supply_register_by_name (regcache, "fctrl", &val);
58caa3dc
DJ
272
273 val = fp->fstat & 0xFFFF;
442ea881 274 supply_register_by_name (regcache, "fstat", &val);
58caa3dc
DJ
275
276 /* Generate the form of ftag data that GDB expects. */
277 top = (fp->fstat >> 11) & 0x7;
278 val = 0;
279 for (i = 7; i >= 0; i--)
280 {
281 int tag;
73725ff3 282 if (fp->ftag & (1 << i))
58caa3dc
DJ
283 tag = i387_ftag (fp, (i + 8 - top) % 8);
284 else
285 tag = 3;
286 val |= tag << (2 * i);
287 }
442ea881 288 supply_register_by_name (regcache, "ftag", &val);
58caa3dc
DJ
289
290 val = fp->fiseg & 0xFFFF;
442ea881 291 supply_register_by_name (regcache, "fiseg", &val);
58caa3dc
DJ
292
293 val = fp->foseg & 0xFFFF;
442ea881 294 supply_register_by_name (regcache, "foseg", &val);
58caa3dc
DJ
295
296 val = (fp->fop) & 0x7FF;
442ea881 297 supply_register_by_name (regcache, "fop", &val);
58caa3dc 298}
This page took 0.849305 seconds and 4 git commands to generate.