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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [gdb/] [gdbserver/] [i387-fp.c] - Blame information for rev 25

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 jlechner
/* i387-specific utility functions, for the remote server for GDB.
2
   Copyright (C) 2000, 2001, 2002, 2005, 2007, 2008
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 (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 (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 10);
85
 
86
  collect_register_by_name ("fioff", &fp->fioff);
87
  collect_register_by_name ("fooff", &fp->fooff);
88
 
89
  /* This one's 11 bits... */
90
  collect_register_by_name ("fop", &val2);
91
  fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
92
 
93
  /* Some registers are 16-bit.  */
94
  collect_register_by_name ("fctrl", &val);
95
  fp->fctrl = val;
96
 
97
  collect_register_by_name ("fstat", &val);
98
  val &= 0xFFFF;
99
  fp->fstat = val;
100
 
101
  collect_register_by_name ("ftag", &val);
102
  val &= 0xFFFF;
103
  fp->ftag = val;
104
 
105
  collect_register_by_name ("fiseg", &val);
106
  val &= 0xFFFF;
107
  fp->fiseg = val;
108
 
109
  collect_register_by_name ("foseg", &val);
110
  val &= 0xFFFF;
111
  fp->foseg = val;
112
}
113
 
114
void
115
i387_fsave_to_cache (const void *buf)
116
{
117
  struct i387_fsave *fp = (struct i387_fsave *) buf;
118
  int i;
119
  int st0_regnum = find_regno ("st0");
120
  unsigned long val;
121
 
122
  for (i = 0; i < 8; i++)
123
    supply_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 10);
124
 
125
  supply_register_by_name ("fioff", &fp->fioff);
126
  supply_register_by_name ("fooff", &fp->fooff);
127
 
128
  /* Some registers are 16-bit.  */
129
  val = fp->fctrl & 0xFFFF;
130
  supply_register_by_name ("fctrl", &val);
131
 
132
  val = fp->fstat & 0xFFFF;
133
  supply_register_by_name ("fstat", &val);
134
 
135
  val = fp->ftag & 0xFFFF;
136
  supply_register_by_name ("ftag", &val);
137
 
138
  val = fp->fiseg & 0xFFFF;
139
  supply_register_by_name ("fiseg", &val);
140
 
141
  val = fp->foseg & 0xFFFF;
142
  supply_register_by_name ("foseg", &val);
143
 
144
  /* fop has only 11 valid bits.  */
145
  val = (fp->fop) & 0x7FF;
146
  supply_register_by_name ("fop", &val);
147
}
148
 
149
void
150
i387_cache_to_fxsave (void *buf)
151
{
152
  struct i387_fxsave *fp = (struct i387_fxsave *) buf;
153
  int i;
154
  int st0_regnum = find_regno ("st0");
155
  int xmm0_regnum = find_regno ("xmm0");
156
  unsigned long val, val2;
157
 
158
  for (i = 0; i < 8; i++)
159
    collect_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 16);
160
  for (i = 0; i < num_xmm_registers; i++)
161
    collect_register (i + xmm0_regnum, ((char *) &fp->xmm_space[0]) + i * 16);
162
 
163
  collect_register_by_name ("fioff", &fp->fioff);
164
  collect_register_by_name ("fooff", &fp->fooff);
165
  collect_register_by_name ("mxcsr", &fp->mxcsr);
166
 
167
  /* This one's 11 bits... */
168
  collect_register_by_name ("fop", &val2);
169
  fp->fop = (val2 & 0x7FF) | (fp->fop & 0xF800);
170
 
171
  /* Some registers are 16-bit.  */
172
  collect_register_by_name ("fctrl", &val);
173
  fp->fctrl = val;
174
 
175
  collect_register_by_name ("fstat", &val);
176
  fp->fstat = val;
177
 
178
  /* Convert to the simplifed tag form stored in fxsave data.  */
179
  collect_register_by_name ("ftag", &val);
180
  val &= 0xFFFF;
181
  val2 = 0;
182
  for (i = 7; i >= 0; i--)
183
    {
184
      int tag = (val >> (i * 2)) & 3;
185
 
186
      if (tag != 3)
187
        val2 |= (1 << i);
188
    }
189
  fp->ftag = val2;
190
 
191
  collect_register_by_name ("fiseg", &val);
192
  fp->fiseg = val;
193
 
194
  collect_register_by_name ("foseg", &val);
195
  fp->foseg = val;
196
}
197
 
198
static int
199
i387_ftag (struct i387_fxsave *fp, int regno)
200
{
201
  unsigned char *raw = &fp->st_space[regno * 16];
202
  unsigned int exponent;
203
  unsigned long fraction[2];
204
  int integer;
205
 
206
  integer = raw[7] & 0x80;
207
  exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
208
  fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
209
  fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
210
                 | (raw[5] << 8) | raw[4]);
211
 
212
  if (exponent == 0x7fff)
213
    {
214
      /* Special.  */
215
      return (2);
216
    }
217
  else if (exponent == 0x0000)
218
    {
219
      if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
220
        {
221
          /* Zero.  */
222
          return (1);
223
        }
224
      else
225
        {
226
          /* Special.  */
227
          return (2);
228
        }
229
    }
230
  else
231
    {
232
      if (integer)
233
        {
234
          /* Valid.  */
235
          return (0);
236
        }
237
      else
238
        {
239
          /* Special.  */
240
          return (2);
241
        }
242
    }
243
}
244
 
245
void
246
i387_fxsave_to_cache (const void *buf)
247
{
248
  struct i387_fxsave *fp = (struct i387_fxsave *) buf;
249
  int i, top;
250
  int st0_regnum = find_regno ("st0");
251
  int xmm0_regnum = find_regno ("xmm0");
252
  unsigned long val;
253
 
254
  for (i = 0; i < 8; i++)
255
    supply_register (i + st0_regnum, ((char *) &fp->st_space[0]) + i * 16);
256
  for (i = 0; i < num_xmm_registers; i++)
257
    supply_register (i + xmm0_regnum, ((char *) &fp->xmm_space[0]) + i * 16);
258
 
259
  supply_register_by_name ("fioff", &fp->fioff);
260
  supply_register_by_name ("fooff", &fp->fooff);
261
  supply_register_by_name ("mxcsr", &fp->mxcsr);
262
 
263
  /* Some registers are 16-bit.  */
264
  val = fp->fctrl & 0xFFFF;
265
  supply_register_by_name ("fctrl", &val);
266
 
267
  val = fp->fstat & 0xFFFF;
268
  supply_register_by_name ("fstat", &val);
269
 
270
  /* Generate the form of ftag data that GDB expects.  */
271
  top = (fp->fstat >> 11) & 0x7;
272
  val = 0;
273
  for (i = 7; i >= 0; i--)
274
    {
275
      int tag;
276
      if (fp->ftag & (1 << i))
277
        tag = i387_ftag (fp, (i + 8 - top) % 8);
278
      else
279
        tag = 3;
280
      val |= tag << (2 * i);
281
    }
282
  supply_register_by_name ("ftag", &val);
283
 
284
  val = fp->fiseg & 0xFFFF;
285
  supply_register_by_name ("fiseg", &val);
286
 
287
  val = fp->foseg & 0xFFFF;
288
  supply_register_by_name ("foseg", &val);
289
 
290
  val = (fp->fop) & 0x7FF;
291
  supply_register_by_name ("fop", &val);
292
}

powered by: WebSVN 2.1.0

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