don't keep a gdb-specific date
[external/binutils.git] / gdb / gdbserver / i387-fp.c
1 /* i387-specific utility functions, for the remote server for GDB.
2    Copyright (C) 2000-2013 Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18
19 #include "server.h"
20 #include "i387-fp.h"
21 #include "i386-xstate.h"
22
23 /* Note: These functions preserve the reserved bits in control registers.
24    However, gdbserver promptly throws away that information.  */
25
26 /* These structs should have the proper sizes and alignment on both
27    i386 and x86-64 machines.  */
28
29 struct i387_fsave {
30   /* All these are only sixteen bits, plus padding, except for fop (which
31      is only eleven bits), and fooff / fioff (which are 32 bits each).  */
32   unsigned short fctrl;
33   unsigned short pad1;
34   unsigned short fstat;
35   unsigned short pad2;
36   unsigned short ftag;
37   unsigned short pad3;
38   unsigned int fioff;
39   unsigned short fiseg;
40   unsigned short fop;
41   unsigned int fooff;
42   unsigned short foseg;
43   unsigned short pad4;
44
45   /* Space for eight 80-bit FP values.  */
46   unsigned char st_space[80];
47 };
48
49 struct i387_fxsave {
50   /* All these are only sixteen bits, plus padding, except for fop (which
51      is only eleven bits), and fooff / fioff (which are 32 bits each).  */
52   unsigned short fctrl;
53   unsigned short fstat;
54   unsigned short ftag;
55   unsigned short fop;
56   unsigned int fioff;
57   unsigned short fiseg;
58   unsigned short pad1;
59   unsigned int fooff;
60   unsigned short foseg;
61   unsigned short pad12;
62
63   unsigned int mxcsr;
64   unsigned int pad3;
65
66   /* Space for eight 80-bit FP values in 128-bit spaces.  */
67   unsigned char st_space[128];
68
69   /* Space for eight 128-bit XMM values, or 16 on x86-64.  */
70   unsigned char xmm_space[256];
71 };
72
73 struct i387_xsave {
74   /* All these are only sixteen bits, plus padding, except for fop (which
75      is only eleven bits), and fooff / fioff (which are 32 bits each).  */
76   unsigned short fctrl;
77   unsigned short fstat;
78   unsigned short ftag;
79   unsigned short fop;
80   unsigned int fioff;
81   unsigned short fiseg;
82   unsigned short pad1;
83   unsigned int fooff;
84   unsigned short foseg;
85   unsigned short pad12;
86
87   unsigned int mxcsr;
88   unsigned int mxcsr_mask;
89
90   /* Space for eight 80-bit FP values in 128-bit spaces.  */
91   unsigned char st_space[128];
92
93   /* Space for eight 128-bit XMM values, or 16 on x86-64.  */
94   unsigned char xmm_space[256];
95
96   unsigned char reserved1[48];
97
98   /* The extended control register 0 (the XFEATURE_ENABLED_MASK
99      register).  */
100   unsigned long long xcr0;
101
102   unsigned char reserved2[40];
103
104   /* The XSTATE_BV bit vector.  */
105   unsigned long long xstate_bv;
106
107   unsigned char reserved3[56];
108
109   /* Space for eight upper 128-bit YMM values, or 16 on x86-64.  */
110   unsigned char ymmh_space[256];
111 };
112
113 void
114 i387_cache_to_fsave (struct regcache *regcache, void *buf)
115 {
116   struct i387_fsave *fp = (struct i387_fsave *) buf;
117   int i;
118   int st0_regnum = find_regno (regcache->tdesc, "st0");
119   unsigned long val, val2;
120
121   for (i = 0; i < 8; i++)
122     collect_register (regcache, i + st0_regnum,
123                       ((char *) &fp->st_space[0]) + i * 10);
124
125   collect_register_by_name (regcache, "fioff", &fp->fioff);
126   collect_register_by_name (regcache, "fooff", &fp->fooff);
127   
128   /* This one's 11 bits... */
129   collect_register_by_name (regcache, "fop", &val2);
130   fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
131
132   /* Some registers are 16-bit.  */
133   collect_register_by_name (regcache, "fctrl", &val);
134   fp->fctrl = val;
135
136   collect_register_by_name (regcache, "fstat", &val);
137   val &= 0xFFFF;
138   fp->fstat = val;
139
140   collect_register_by_name (regcache, "ftag", &val);
141   val &= 0xFFFF;
142   fp->ftag = val;
143
144   collect_register_by_name (regcache, "fiseg", &val);
145   val &= 0xFFFF;
146   fp->fiseg = val;
147
148   collect_register_by_name (regcache, "foseg", &val);
149   val &= 0xFFFF;
150   fp->foseg = val;
151 }
152
153 void
154 i387_fsave_to_cache (struct regcache *regcache, const void *buf)
155 {
156   struct i387_fsave *fp = (struct i387_fsave *) buf;
157   int i;
158   int st0_regnum = find_regno (regcache->tdesc, "st0");
159   unsigned long val;
160
161   for (i = 0; i < 8; i++)
162     supply_register (regcache, i + st0_regnum,
163                      ((char *) &fp->st_space[0]) + i * 10);
164
165   supply_register_by_name (regcache, "fioff", &fp->fioff);
166   supply_register_by_name (regcache, "fooff", &fp->fooff);
167
168   /* Some registers are 16-bit.  */
169   val = fp->fctrl & 0xFFFF;
170   supply_register_by_name (regcache, "fctrl", &val);
171
172   val = fp->fstat & 0xFFFF;
173   supply_register_by_name (regcache, "fstat", &val);
174
175   val = fp->ftag & 0xFFFF;
176   supply_register_by_name (regcache, "ftag", &val);
177
178   val = fp->fiseg & 0xFFFF;
179   supply_register_by_name (regcache, "fiseg", &val);
180
181   val = fp->foseg & 0xFFFF;
182   supply_register_by_name (regcache, "foseg", &val);
183
184   /* fop has only 11 valid bits.  */
185   val = (fp->fop) & 0x7FF;
186   supply_register_by_name (regcache, "fop", &val);
187 }
188
189 void
190 i387_cache_to_fxsave (struct regcache *regcache, void *buf)
191 {
192   struct i387_fxsave *fp = (struct i387_fxsave *) buf;
193   int i;
194   int st0_regnum = find_regno (regcache->tdesc, "st0");
195   int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
196   unsigned long val, val2;
197   /* Amd64 has 16 xmm regs; I386 has 8 xmm regs.  */
198   int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
199
200   for (i = 0; i < 8; i++)
201     collect_register (regcache, i + st0_regnum,
202                       ((char *) &fp->st_space[0]) + i * 16);
203   for (i = 0; i < num_xmm_registers; i++)
204     collect_register (regcache, i + xmm0_regnum,
205                       ((char *) &fp->xmm_space[0]) + i * 16);
206
207   collect_register_by_name (regcache, "fioff", &fp->fioff);
208   collect_register_by_name (regcache, "fooff", &fp->fooff);
209   collect_register_by_name (regcache, "mxcsr", &fp->mxcsr);
210
211   /* This one's 11 bits... */
212   collect_register_by_name (regcache, "fop", &val2);
213   fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
214
215   /* Some registers are 16-bit.  */
216   collect_register_by_name (regcache, "fctrl", &val);
217   fp->fctrl = val;
218
219   collect_register_by_name (regcache, "fstat", &val);
220   fp->fstat = val;
221
222   /* Convert to the simplifed tag form stored in fxsave data.  */
223   collect_register_by_name (regcache, "ftag", &val);
224   val &= 0xFFFF;
225   val2 = 0;
226   for (i = 7; i >= 0; i--)
227     {
228       int tag = (val >> (i * 2)) & 3;
229
230       if (tag != 3)
231         val2 |= (1 << i);
232     }
233   fp->ftag = val2;
234
235   collect_register_by_name (regcache, "fiseg", &val);
236   fp->fiseg = val;
237
238   collect_register_by_name (regcache, "foseg", &val);
239   fp->foseg = val;
240 }
241
242 void
243 i387_cache_to_xsave (struct regcache *regcache, void *buf)
244 {
245   struct i387_xsave *fp = (struct i387_xsave *) buf;
246   int i;
247   unsigned long val, val2;
248   unsigned int clear_bv;
249   unsigned long long xstate_bv = 0;
250   char raw[16];
251   char *p;
252   /* Amd64 has 16 xmm regs; I386 has 8 xmm regs.  */
253   int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
254
255   /* The supported bits in `xstat_bv' are 1 byte.  Clear part in
256      vector registers if its bit in xstat_bv is zero.  */
257   clear_bv = (~fp->xstate_bv) & x86_xcr0;
258
259   /* Clear part in x87 and vector registers if its bit in xstat_bv is
260      zero.  */
261   if (clear_bv)
262     {
263       if ((clear_bv & I386_XSTATE_X87))
264         for (i = 0; i < 8; i++)
265           memset (((char *) &fp->st_space[0]) + i * 16, 0, 10);
266
267       if ((clear_bv & I386_XSTATE_SSE))
268         for (i = 0; i < num_xmm_registers; i++) 
269           memset (((char *) &fp->xmm_space[0]) + i * 16, 0, 16);
270
271       if ((clear_bv & I386_XSTATE_AVX))
272         for (i = 0; i < num_xmm_registers; i++) 
273           memset (((char *) &fp->ymmh_space[0]) + i * 16, 0, 16);
274     }
275
276   /* Check if any x87 registers are changed.  */
277   if ((x86_xcr0 & I386_XSTATE_X87))
278     {
279       int st0_regnum = find_regno (regcache->tdesc, "st0");
280
281       for (i = 0; i < 8; i++)
282         {
283           collect_register (regcache, i + st0_regnum, raw);
284           p = ((char *) &fp->st_space[0]) + i * 16;
285           if (memcmp (raw, p, 10))
286             {
287               xstate_bv |= I386_XSTATE_X87;
288               memcpy (p, raw, 10);
289             }
290         }
291     }
292
293   /* Check if any SSE registers are changed.  */
294   if ((x86_xcr0 & I386_XSTATE_SSE))
295     {
296       int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
297
298       for (i = 0; i < num_xmm_registers; i++) 
299         {
300           collect_register (regcache, i + xmm0_regnum, raw);
301           p = ((char *) &fp->xmm_space[0]) + i * 16;
302           if (memcmp (raw, p, 16))
303             {
304               xstate_bv |= I386_XSTATE_SSE;
305               memcpy (p, raw, 16);
306             }
307         }
308     }
309
310   /* Check if any AVX registers are changed.  */
311   if ((x86_xcr0 & I386_XSTATE_AVX))
312     {
313       int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
314
315       for (i = 0; i < num_xmm_registers; i++) 
316         {
317           collect_register (regcache, i + ymm0h_regnum, raw);
318           p = ((char *) &fp->ymmh_space[0]) + i * 16;
319           if (memcmp (raw, p, 16))
320             {
321               xstate_bv |= I386_XSTATE_AVX;
322               memcpy (p, raw, 16);
323             }
324         }
325     }
326
327   /* Update the corresponding bits in xstate_bv if any SSE/AVX
328      registers are changed.  */
329   fp->xstate_bv |= xstate_bv;
330
331   collect_register_by_name (regcache, "fioff", &fp->fioff);
332   collect_register_by_name (regcache, "fooff", &fp->fooff);
333   collect_register_by_name (regcache, "mxcsr", &fp->mxcsr);
334
335   /* This one's 11 bits... */
336   collect_register_by_name (regcache, "fop", &val2);
337   fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
338
339   /* Some registers are 16-bit.  */
340   collect_register_by_name (regcache, "fctrl", &val);
341   fp->fctrl = val;
342
343   collect_register_by_name (regcache, "fstat", &val);
344   fp->fstat = val;
345
346   /* Convert to the simplifed tag form stored in fxsave data.  */
347   collect_register_by_name (regcache, "ftag", &val);
348   val &= 0xFFFF;
349   val2 = 0;
350   for (i = 7; i >= 0; i--)
351     {
352       int tag = (val >> (i * 2)) & 3;
353
354       if (tag != 3)
355         val2 |= (1 << i);
356     }
357   fp->ftag = val2;
358
359   collect_register_by_name (regcache, "fiseg", &val);
360   fp->fiseg = val;
361
362   collect_register_by_name (regcache, "foseg", &val);
363   fp->foseg = val;
364 }
365
366 static int
367 i387_ftag (struct i387_fxsave *fp, int regno)
368 {
369   unsigned char *raw = &fp->st_space[regno * 16];
370   unsigned int exponent;
371   unsigned long fraction[2];
372   int integer;
373
374   integer = raw[7] & 0x80;
375   exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
376   fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
377   fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
378                  | (raw[5] << 8) | raw[4]);
379
380   if (exponent == 0x7fff)
381     {
382       /* Special.  */
383       return (2);
384     }
385   else if (exponent == 0x0000)
386     {
387       if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
388         {
389           /* Zero.  */
390           return (1);
391         }
392       else
393         {
394           /* Special.  */
395           return (2);
396         }
397     }
398   else
399     {
400       if (integer)
401         {
402           /* Valid.  */
403           return (0);
404         }
405       else
406         {
407           /* Special.  */
408           return (2);
409         }
410     }
411 }
412
413 void
414 i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
415 {
416   struct i387_fxsave *fp = (struct i387_fxsave *) buf;
417   int i, top;
418   int st0_regnum = find_regno (regcache->tdesc, "st0");
419   int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
420   unsigned long val;
421   /* Amd64 has 16 xmm regs; I386 has 8 xmm regs.  */
422   int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
423
424   for (i = 0; i < 8; i++)
425     supply_register (regcache, i + st0_regnum,
426                      ((char *) &fp->st_space[0]) + i * 16);
427   for (i = 0; i < num_xmm_registers; i++)
428     supply_register (regcache, i + xmm0_regnum,
429                      ((char *) &fp->xmm_space[0]) + i * 16);
430
431   supply_register_by_name (regcache, "fioff", &fp->fioff);
432   supply_register_by_name (regcache, "fooff", &fp->fooff);
433   supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
434
435   /* Some registers are 16-bit.  */
436   val = fp->fctrl & 0xFFFF;
437   supply_register_by_name (regcache, "fctrl", &val);
438
439   val = fp->fstat & 0xFFFF;
440   supply_register_by_name (regcache, "fstat", &val);
441
442   /* Generate the form of ftag data that GDB expects.  */
443   top = (fp->fstat >> 11) & 0x7;
444   val = 0;
445   for (i = 7; i >= 0; i--)
446     {
447       int tag;
448       if (fp->ftag & (1 << i))
449         tag = i387_ftag (fp, (i + 8 - top) % 8);
450       else
451         tag = 3;
452       val |= tag << (2 * i);
453     }
454   supply_register_by_name (regcache, "ftag", &val);
455
456   val = fp->fiseg & 0xFFFF;
457   supply_register_by_name (regcache, "fiseg", &val);
458
459   val = fp->foseg & 0xFFFF;
460   supply_register_by_name (regcache, "foseg", &val);
461
462   val = (fp->fop) & 0x7FF;
463   supply_register_by_name (regcache, "fop", &val);
464 }
465
466 void
467 i387_xsave_to_cache (struct regcache *regcache, const void *buf)
468 {
469   struct i387_xsave *fp = (struct i387_xsave *) buf;
470   struct i387_fxsave *fxp = (struct i387_fxsave *) buf;
471   int i, top;
472   unsigned long val;
473   unsigned int clear_bv;
474   gdb_byte *p;
475   /* Amd64 has 16 xmm regs; I386 has 8 xmm regs.  */
476   int num_xmm_registers = register_size (regcache->tdesc, 0) == 8 ? 16 : 8;
477
478   /* The supported bits in `xstat_bv' are 1 byte.  Clear part in
479      vector registers if its bit in xstat_bv is zero.  */
480   clear_bv = (~fp->xstate_bv) & x86_xcr0;
481
482   /* Check if any x87 registers are changed.  */
483   if ((x86_xcr0 & I386_XSTATE_X87) != 0)
484     {
485       int st0_regnum = find_regno (regcache->tdesc, "st0");
486
487       if ((clear_bv & I386_XSTATE_X87) != 0)
488         {
489           for (i = 0; i < 8; i++)
490             supply_register_zeroed (regcache, i + st0_regnum);
491         }
492       else
493         {
494           p = (gdb_byte *) &fp->st_space[0];
495           for (i = 0; i < 8; i++)
496             supply_register (regcache, i + st0_regnum, p + i * 16);
497         }
498     }
499
500   if ((x86_xcr0 & I386_XSTATE_SSE) != 0)
501     {
502       int xmm0_regnum = find_regno (regcache->tdesc, "xmm0");
503
504       if ((clear_bv & I386_XSTATE_SSE))
505         {
506           for (i = 0; i < num_xmm_registers; i++)
507             supply_register_zeroed (regcache, i + xmm0_regnum);
508         }
509       else
510         {
511           p = (gdb_byte *) &fp->xmm_space[0];
512           for (i = 0; i < num_xmm_registers; i++)
513             supply_register (regcache, i + xmm0_regnum, p + i * 16);
514         }
515     }
516
517   if ((x86_xcr0 & I386_XSTATE_AVX) != 0)
518     {
519       int ymm0h_regnum = find_regno (regcache->tdesc, "ymm0h");
520
521       if ((clear_bv & I386_XSTATE_AVX) != 0)
522         {
523           for (i = 0; i < num_xmm_registers; i++)
524             supply_register_zeroed (regcache, i + ymm0h_regnum);
525         }
526       else
527         {
528           p = (gdb_byte *) &fp->ymmh_space[0];
529           for (i = 0; i < num_xmm_registers; i++)
530             supply_register (regcache, i + ymm0h_regnum, p + i * 16);
531         }
532     }
533
534   supply_register_by_name (regcache, "fioff", &fp->fioff);
535   supply_register_by_name (regcache, "fooff", &fp->fooff);
536   supply_register_by_name (regcache, "mxcsr", &fp->mxcsr);
537
538   /* Some registers are 16-bit.  */
539   val = fp->fctrl & 0xFFFF;
540   supply_register_by_name (regcache, "fctrl", &val);
541
542   val = fp->fstat & 0xFFFF;
543   supply_register_by_name (regcache, "fstat", &val);
544
545   /* Generate the form of ftag data that GDB expects.  */
546   top = (fp->fstat >> 11) & 0x7;
547   val = 0;
548   for (i = 7; i >= 0; i--)
549     {
550       int tag;
551       if (fp->ftag & (1 << i))
552         tag = i387_ftag (fxp, (i + 8 - top) % 8);
553       else
554         tag = 3;
555       val |= tag << (2 * i);
556     }
557   supply_register_by_name (regcache, "ftag", &val);
558
559   val = fp->fiseg & 0xFFFF;
560   supply_register_by_name (regcache, "fiseg", &val);
561
562   val = fp->foseg & 0xFFFF;
563   supply_register_by_name (regcache, "foseg", &val);
564
565   val = (fp->fop) & 0x7FF;
566   supply_register_by_name (regcache, "fop", &val);
567 }
568
569 /* Default to SSE.  */
570 unsigned long long x86_xcr0 = I386_XSTATE_SSE_MASK;