OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [gdbserver/] [i387-fp.c] - Blame information for rev 231

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* i387-specific utility functions, for the remote server for GDB.
2
   Copyright (C) 2000, 2001, 2002, 2005, 2007, 2008, 2009, 2010
3
   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 3 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, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "server.h"
21
#include "i387-fp.h"
22
 
23
int 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
 
31
struct 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).  */
34
  unsigned short fctrl;
35
  unsigned short pad1;
36
  unsigned short fstat;
37
  unsigned short pad2;
38
  unsigned short ftag;
39
  unsigned short pad3;
40
  unsigned int fioff;
41
  unsigned short fiseg;
42
  unsigned short fop;
43
  unsigned int fooff;
44
  unsigned short foseg;
45
  unsigned short pad4;
46
 
47
  /* Space for eight 80-bit FP values.  */
48
  unsigned char st_space[80];
49
};
50
 
51
struct 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;
59
  unsigned short fiseg;
60
  unsigned short pad1;
61
  unsigned int fooff;
62
  unsigned short foseg;
63
  unsigned short pad12;
64
 
65
  unsigned int mxcsr;
66
  unsigned int pad3;
67
 
68
  /* Space for eight 80-bit FP values in 128-bit spaces.  */
69
  unsigned char st_space[128];
70
 
71
  /* Space for eight 128-bit XMM values, or 16 on x86-64.  */
72
  unsigned char xmm_space[256];
73
};
74
 
75
void
76
i387_cache_to_fsave (struct regcache *regcache, void *buf)
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++)
84
    collect_register (regcache, i + st0_regnum,
85
                      ((char *) &fp->st_space[0]) + i * 10);
86
 
87
  collect_register_by_name (regcache, "fioff", &fp->fioff);
88
  collect_register_by_name (regcache, "fooff", &fp->fooff);
89
 
90
  /* This one's 11 bits... */
91
  collect_register_by_name (regcache, "fop", &val2);
92
  fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
93
 
94
  /* Some registers are 16-bit.  */
95
  collect_register_by_name (regcache, "fctrl", &val);
96
  fp->fctrl = val;
97
 
98
  collect_register_by_name (regcache, "fstat", &val);
99
  val &= 0xFFFF;
100
  fp->fstat = val;
101
 
102
  collect_register_by_name (regcache, "ftag", &val);
103
  val &= 0xFFFF;
104
  fp->ftag = val;
105
 
106
  collect_register_by_name (regcache, "fiseg", &val);
107
  val &= 0xFFFF;
108
  fp->fiseg = val;
109
 
110
  collect_register_by_name (regcache, "foseg", &val);
111
  val &= 0xFFFF;
112
  fp->foseg = val;
113
}
114
 
115
void
116
i387_fsave_to_cache (struct regcache *regcache, const void *buf)
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++)
124
    supply_register (regcache, i + st0_regnum,
125
                     ((char *) &fp->st_space[0]) + i * 10);
126
 
127
  supply_register_by_name (regcache, "fioff", &fp->fioff);
128
  supply_register_by_name (regcache, "fooff", &fp->fooff);
129
 
130
  /* Some registers are 16-bit.  */
131
  val = fp->fctrl & 0xFFFF;
132
  supply_register_by_name (regcache, "fctrl", &val);
133
 
134
  val = fp->fstat & 0xFFFF;
135
  supply_register_by_name (regcache, "fstat", &val);
136
 
137
  val = fp->ftag & 0xFFFF;
138
  supply_register_by_name (regcache, "ftag", &val);
139
 
140
  val = fp->fiseg & 0xFFFF;
141
  supply_register_by_name (regcache, "fiseg", &val);
142
 
143
  val = fp->foseg & 0xFFFF;
144
  supply_register_by_name (regcache, "foseg", &val);
145
 
146
  /* fop has only 11 valid bits.  */
147
  val = (fp->fop) & 0x7FF;
148
  supply_register_by_name (regcache, "fop", &val);
149
}
150
 
151
void
152
i387_cache_to_fxsave (struct regcache *regcache, void *buf)
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++)
161
    collect_register (regcache, i + st0_regnum,
162
                      ((char *) &fp->st_space[0]) + i * 16);
163
  for (i = 0; i < num_xmm_registers; i++)
164
    collect_register (regcache, i + xmm0_regnum,
165
                      ((char *) &fp->xmm_space[0]) + i * 16);
166
 
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);
170
 
171
  /* This one's 11 bits... */
172
  collect_register_by_name (regcache, "fop", &val2);
173
  fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
174
 
175
  /* Some registers are 16-bit.  */
176
  collect_register_by_name (regcache, "fctrl", &val);
177
  fp->fctrl = val;
178
 
179
  collect_register_by_name (regcache, "fstat", &val);
180
  fp->fstat = val;
181
 
182
  /* Convert to the simplifed tag form stored in fxsave data.  */
183
  collect_register_by_name (regcache, "ftag", &val);
184
  val &= 0xFFFF;
185
  val2 = 0;
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
    }
193
  fp->ftag = val2;
194
 
195
  collect_register_by_name (regcache, "fiseg", &val);
196
  fp->fiseg = val;
197
 
198
  collect_register_by_name (regcache, "foseg", &val);
199
  fp->foseg = val;
200
}
201
 
202
static int
203
i387_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)
214
                 | (raw[5] << 8) | raw[4]);
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)
224
        {
225
          /* Zero.  */
226
          return (1);
227
        }
228
      else
229
        {
230
          /* Special.  */
231
          return (2);
232
        }
233
    }
234
  else
235
    {
236
      if (integer)
237
        {
238
          /* Valid.  */
239
          return (0);
240
        }
241
      else
242
        {
243
          /* Special.  */
244
          return (2);
245
        }
246
    }
247
}
248
 
249
void
250
i387_fxsave_to_cache (struct regcache *regcache, const void *buf)
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++)
259
    supply_register (regcache, i + st0_regnum,
260
                     ((char *) &fp->st_space[0]) + i * 16);
261
  for (i = 0; i < num_xmm_registers; i++)
262
    supply_register (regcache, i + xmm0_regnum,
263
                     ((char *) &fp->xmm_space[0]) + i * 16);
264
 
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);
268
 
269
  /* Some registers are 16-bit.  */
270
  val = fp->fctrl & 0xFFFF;
271
  supply_register_by_name (regcache, "fctrl", &val);
272
 
273
  val = fp->fstat & 0xFFFF;
274
  supply_register_by_name (regcache, "fstat", &val);
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;
282
      if (fp->ftag & (1 << i))
283
        tag = i387_ftag (fp, (i + 8 - top) % 8);
284
      else
285
        tag = 3;
286
      val |= tag << (2 * i);
287
    }
288
  supply_register_by_name (regcache, "ftag", &val);
289
 
290
  val = fp->fiseg & 0xFFFF;
291
  supply_register_by_name (regcache, "fiseg", &val);
292
 
293
  val = fp->foseg & 0xFFFF;
294
  supply_register_by_name (regcache, "foseg", &val);
295
 
296
  val = (fp->fop) & 0x7FF;
297
  supply_register_by_name (regcache, "fop", &val);
298
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.