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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [gdbserver/] [i387-fp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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