Imported Upstream version 7.5
[platform/upstream/gdb.git] / gdb / i387-tdep.c
1 /* Intel 387 floating point stuff.
2
3    Copyright (C) 1988-1989, 1991-1994, 1998-2005, 2007-2012 Free
4    Software Foundation, Inc.
5
6    This file is part of GDB.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21 #include "defs.h"
22 #include "doublest.h"
23 #include "floatformat.h"
24 #include "frame.h"
25 #include "gdbcore.h"
26 #include "inferior.h"
27 #include "language.h"
28 #include "regcache.h"
29 #include "value.h"
30
31 #include "gdb_assert.h"
32 #include "gdb_string.h"
33
34 #include "i386-tdep.h"
35 #include "i387-tdep.h"
36 #include "i386-xstate.h"
37
38 /* Print the floating point number specified by RAW.  */
39
40 static void
41 print_i387_value (struct gdbarch *gdbarch,
42                   const gdb_byte *raw, struct ui_file *file)
43 {
44   DOUBLEST value;
45
46   /* Using extract_typed_floating here might affect the representation
47      of certain numbers such as NaNs, even if GDB is running natively.
48      This is fine since our caller already detects such special
49      numbers and we print the hexadecimal representation anyway.  */
50   value = extract_typed_floating (raw, i387_ext_type (gdbarch));
51
52   /* We try to print 19 digits.  The last digit may or may not contain
53      garbage, but we'd better print one too many.  We need enough room
54      to print the value, 1 position for the sign, 1 for the decimal
55      point, 19 for the digits and 6 for the exponent adds up to 27.  */
56 #ifdef PRINTF_HAS_LONG_DOUBLE
57   fprintf_filtered (file, " %-+27.19Lg", (long double) value);
58 #else
59   fprintf_filtered (file, " %-+27.19g", (double) value);
60 #endif
61 }
62
63 /* Print the classification for the register contents RAW.  */
64
65 static void
66 print_i387_ext (struct gdbarch *gdbarch,
67                 const gdb_byte *raw, struct ui_file *file)
68 {
69   int sign;
70   int integer;
71   unsigned int exponent;
72   unsigned long fraction[2];
73
74   sign = raw[9] & 0x80;
75   integer = raw[7] & 0x80;
76   exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
77   fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
78   fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
79                  | (raw[5] << 8) | raw[4]);
80
81   if (exponent == 0x7fff && integer)
82     {
83       if (fraction[0] == 0x00000000 && fraction[1] == 0x00000000)
84         /* Infinity.  */
85         fprintf_filtered (file, " %cInf", (sign ? '-' : '+'));
86       else if (sign && fraction[0] == 0x00000000 && fraction[1] == 0x40000000)
87         /* Real Indefinite (QNaN).  */
88         fputs_unfiltered (" Real Indefinite (QNaN)", file);
89       else if (fraction[1] & 0x40000000)
90         /* QNaN.  */
91         fputs_filtered (" QNaN", file);
92       else
93         /* SNaN.  */
94         fputs_filtered (" SNaN", file);
95     }
96   else if (exponent < 0x7fff && exponent > 0x0000 && integer)
97     /* Normal.  */
98     print_i387_value (gdbarch, raw, file);
99   else if (exponent == 0x0000)
100     {
101       /* Denormal or zero.  */
102       print_i387_value (gdbarch, raw, file);
103       
104       if (integer)
105         /* Pseudo-denormal.  */
106         fputs_filtered (" Pseudo-denormal", file);
107       else if (fraction[0] || fraction[1])
108         /* Denormal.  */
109         fputs_filtered (" Denormal", file);
110     }
111   else
112     /* Unsupported.  */
113     fputs_filtered (" Unsupported", file);
114 }
115
116 /* Print the status word STATUS.  If STATUS_P is false, then STATUS
117    was unavailable.  */
118
119 static void
120 print_i387_status_word (int status_p,
121                         unsigned int status, struct ui_file *file)
122 {
123   fprintf_filtered (file, "Status Word:         ");
124   if (!status_p)
125     {
126       fprintf_filtered (file, "%s\n", _("<unavailable>"));
127       return;
128     }
129
130   fprintf_filtered (file, "%s", hex_string_custom (status, 4));
131   fputs_filtered ("  ", file);
132   fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : "  ");
133   fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : "  ");
134   fprintf_filtered (file, " %s", (status & 0x0004) ? "ZE" : "  ");
135   fprintf_filtered (file, " %s", (status & 0x0008) ? "OE" : "  ");
136   fprintf_filtered (file, " %s", (status & 0x0010) ? "UE" : "  ");
137   fprintf_filtered (file, " %s", (status & 0x0020) ? "PE" : "  ");
138   fputs_filtered ("  ", file);
139   fprintf_filtered (file, " %s", (status & 0x0080) ? "ES" : "  ");
140   fputs_filtered ("  ", file);
141   fprintf_filtered (file, " %s", (status & 0x0040) ? "SF" : "  ");
142   fputs_filtered ("  ", file);
143   fprintf_filtered (file, " %s", (status & 0x0100) ? "C0" : "  ");
144   fprintf_filtered (file, " %s", (status & 0x0200) ? "C1" : "  ");
145   fprintf_filtered (file, " %s", (status & 0x0400) ? "C2" : "  ");
146   fprintf_filtered (file, " %s", (status & 0x4000) ? "C3" : "  ");
147
148   fputs_filtered ("\n", file);
149
150   fprintf_filtered (file,
151                     "                       TOP: %d\n", ((status >> 11) & 7));
152 }
153
154 /* Print the control word CONTROL.  If CONTROL_P is false, then
155    CONTROL was unavailable.  */
156
157 static void
158 print_i387_control_word (int control_p,
159                          unsigned int control, struct ui_file *file)
160 {
161   fprintf_filtered (file, "Control Word:        ");
162   if (!control_p)
163     {
164       fprintf_filtered (file, "%s\n", _("<unavailable>"));
165       return;
166     }
167
168   fprintf_filtered (file, "%s", hex_string_custom (control, 4));
169   fputs_filtered ("  ", file);
170   fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : "  ");
171   fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : "  ");
172   fprintf_filtered (file, " %s", (control & 0x0004) ? "ZM" : "  ");
173   fprintf_filtered (file, " %s", (control & 0x0008) ? "OM" : "  ");
174   fprintf_filtered (file, " %s", (control & 0x0010) ? "UM" : "  ");
175   fprintf_filtered (file, " %s", (control & 0x0020) ? "PM" : "  ");
176
177   fputs_filtered ("\n", file);
178
179   fputs_filtered ("                       PC: ", file);
180   switch ((control >> 8) & 3)
181     {
182     case 0:
183       fputs_filtered ("Single Precision (24-bits)\n", file);
184       break;
185     case 1:
186       fputs_filtered ("Reserved\n", file);
187       break;
188     case 2:
189       fputs_filtered ("Double Precision (53-bits)\n", file);
190       break;
191     case 3:
192       fputs_filtered ("Extended Precision (64-bits)\n", file);
193       break;
194     }
195       
196   fputs_filtered ("                       RC: ", file);
197   switch ((control >> 10) & 3)
198     {
199     case 0:
200       fputs_filtered ("Round to nearest\n", file);
201       break;
202     case 1:
203       fputs_filtered ("Round down\n", file);
204       break;
205     case 2:
206       fputs_filtered ("Round up\n", file);
207       break;
208     case 3:
209       fputs_filtered ("Round toward zero\n", file);
210       break;
211     }
212 }
213
214 /* Print out the i387 floating point state.  Note that we ignore FRAME
215    in the code below.  That's OK since floating-point registers are
216    never saved on the stack.  */
217
218 void
219 i387_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
220                        struct frame_info *frame, const char *args)
221 {
222   struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
223   ULONGEST fctrl;
224   int fctrl_p;
225   ULONGEST fstat;
226   int fstat_p;
227   ULONGEST ftag;
228   int ftag_p;
229   ULONGEST fiseg;
230   int fiseg_p;
231   ULONGEST fioff;
232   int fioff_p;
233   ULONGEST foseg;
234   int foseg_p;
235   ULONGEST fooff;
236   int fooff_p;
237   ULONGEST fop;
238   int fop_p;
239   int fpreg;
240   int top;
241
242   gdb_assert (gdbarch == get_frame_arch (frame));
243
244   fctrl_p = read_frame_register_unsigned (frame,
245                                           I387_FCTRL_REGNUM (tdep), &fctrl);
246   fstat_p = read_frame_register_unsigned (frame,
247                                           I387_FSTAT_REGNUM (tdep), &fstat);
248   ftag_p = read_frame_register_unsigned (frame,
249                                          I387_FTAG_REGNUM (tdep), &ftag);
250   fiseg_p = read_frame_register_unsigned (frame,
251                                           I387_FISEG_REGNUM (tdep), &fiseg);
252   fioff_p = read_frame_register_unsigned (frame,
253                                           I387_FIOFF_REGNUM (tdep), &fioff);
254   foseg_p = read_frame_register_unsigned (frame,
255                                           I387_FOSEG_REGNUM (tdep), &foseg);
256   fooff_p = read_frame_register_unsigned (frame,
257                                           I387_FOOFF_REGNUM (tdep), &fooff);
258   fop_p = read_frame_register_unsigned (frame,
259                                         I387_FOP_REGNUM (tdep), &fop);
260
261   if (fstat_p)
262     {
263       top = ((fstat >> 11) & 7);
264
265       for (fpreg = 7; fpreg >= 0; fpreg--)
266         {
267           struct value *regval;
268           int regnum;
269           int i;
270           int tag = -1;
271
272           fprintf_filtered (file, "%sR%d: ", fpreg == top ? "=>" : "  ", fpreg);
273
274           if (ftag_p)
275             {
276               tag = (ftag >> (fpreg * 2)) & 3;
277
278               switch (tag)
279                 {
280                 case 0:
281                   fputs_filtered ("Valid   ", file);
282                   break;
283                 case 1:
284                   fputs_filtered ("Zero    ", file);
285                   break;
286                 case 2:
287                   fputs_filtered ("Special ", file);
288                   break;
289                 case 3:
290                   fputs_filtered ("Empty   ", file);
291                   break;
292                 }
293             }
294           else
295             fputs_filtered ("Unknown ", file);
296
297           regnum = (fpreg + 8 - top) % 8 + I387_ST0_REGNUM (tdep);
298           regval = get_frame_register_value (frame, regnum);
299
300           if (value_entirely_available (regval))
301             {
302               const char *raw = value_contents (regval);
303
304               fputs_filtered ("0x", file);
305               for (i = 9; i >= 0; i--)
306                 fprintf_filtered (file, "%02x", raw[i]);
307
308               if (tag != -1 && tag != 3)
309                 print_i387_ext (gdbarch, raw, file);
310             }
311           else
312             fprintf_filtered (file, "%s", _("<unavailable>"));
313
314           fputs_filtered ("\n", file);
315         }
316     }
317
318   fputs_filtered ("\n", file);
319   print_i387_status_word (fstat_p, fstat, file);
320   print_i387_control_word (fctrl_p, fctrl, file);
321   fprintf_filtered (file, "Tag Word:            %s\n",
322                     ftag_p ? hex_string_custom (ftag, 4) : _("<unavailable>"));
323   fprintf_filtered (file, "Instruction Pointer: %s:",
324                     fiseg_p ? hex_string_custom (fiseg, 2) : _("<unavailable>"));
325   fprintf_filtered (file, "%s\n",
326                     fioff_p ? hex_string_custom (fioff, 8) : _("<unavailable>"));
327   fprintf_filtered (file, "Operand Pointer:     %s:",
328                     foseg_p ? hex_string_custom (foseg, 2) : _("<unavailable>"));
329   fprintf_filtered (file, "%s\n",
330                     fooff_p ? hex_string_custom (fooff, 8) : _("<unavailable>"));
331   fprintf_filtered (file, "Opcode:              %s\n",
332                     fop_p
333                     ? (hex_string_custom (fop ? (fop | 0xd800) : 0, 4))
334                     : _("<unavailable>"));
335 }
336 \f
337
338 /* Return nonzero if a value of type TYPE stored in register REGNUM
339    needs any special handling.  */
340
341 int
342 i387_convert_register_p (struct gdbarch *gdbarch, int regnum,
343                          struct type *type)
344 {
345   if (i386_fp_regnum_p (gdbarch, regnum))
346     {
347       /* Floating point registers must be converted unless we are
348          accessing them in their hardware type.  */
349       if (type == i387_ext_type (gdbarch))
350         return 0;
351       else
352         return 1;
353     }
354
355   return 0;
356 }
357
358 /* Read a value of type TYPE from register REGNUM in frame FRAME, and
359    return its contents in TO.  */
360
361 int
362 i387_register_to_value (struct frame_info *frame, int regnum,
363                         struct type *type, gdb_byte *to,
364                         int *optimizedp, int *unavailablep)
365 {
366   struct gdbarch *gdbarch = get_frame_arch (frame);
367   gdb_byte from[I386_MAX_REGISTER_SIZE];
368
369   gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
370
371   /* We only support floating-point values.  */
372   if (TYPE_CODE (type) != TYPE_CODE_FLT)
373     {
374       warning (_("Cannot convert floating-point register value "
375                "to non-floating-point type."));
376       *optimizedp = *unavailablep = 0;
377       return 0;
378     }
379
380   /* Convert to TYPE.  */
381   if (!get_frame_register_bytes (frame, regnum, 0, TYPE_LENGTH (type),
382                                  from, optimizedp, unavailablep))
383     return 0;
384
385   convert_typed_floating (from, i387_ext_type (gdbarch), to, type);
386   *optimizedp = *unavailablep = 0;
387   return 1;
388 }
389
390 /* Write the contents FROM of a value of type TYPE into register
391    REGNUM in frame FRAME.  */
392
393 void
394 i387_value_to_register (struct frame_info *frame, int regnum,
395                         struct type *type, const gdb_byte *from)
396 {
397   struct gdbarch *gdbarch = get_frame_arch (frame);
398   gdb_byte to[I386_MAX_REGISTER_SIZE];
399
400   gdb_assert (i386_fp_regnum_p (gdbarch, regnum));
401
402   /* We only support floating-point values.  */
403   if (TYPE_CODE (type) != TYPE_CODE_FLT)
404     {
405       warning (_("Cannot convert non-floating-point type "
406                "to floating-point register value."));
407       return;
408     }
409
410   /* Convert from TYPE.  */
411   convert_typed_floating (from, type, to, i387_ext_type (gdbarch));
412   put_frame_register (frame, regnum, to);
413 }
414 \f
415
416 /* Handle FSAVE and FXSAVE formats.  */
417
418 /* At fsave_offset[REGNUM] you'll find the offset to the location in
419    the data structure used by the "fsave" instruction where GDB
420    register REGNUM is stored.  */
421
422 static int fsave_offset[] =
423 {
424   28 + 0 * 10,                  /* %st(0) ...  */
425   28 + 1 * 10,
426   28 + 2 * 10,
427   28 + 3 * 10,
428   28 + 4 * 10,
429   28 + 5 * 10,
430   28 + 6 * 10,
431   28 + 7 * 10,                  /* ... %st(7).  */
432   0,                            /* `fctrl' (16 bits).  */
433   4,                            /* `fstat' (16 bits).  */
434   8,                            /* `ftag' (16 bits).  */
435   16,                           /* `fiseg' (16 bits).  */
436   12,                           /* `fioff'.  */
437   24,                           /* `foseg' (16 bits).  */
438   20,                           /* `fooff'.  */
439   18                            /* `fop' (bottom 11 bits).  */
440 };
441
442 #define FSAVE_ADDR(tdep, fsave, regnum) \
443   (fsave + fsave_offset[regnum - I387_ST0_REGNUM (tdep)])
444 \f
445
446 /* Fill register REGNUM in REGCACHE with the appropriate value from
447    *FSAVE.  This function masks off any of the reserved bits in
448    *FSAVE.  */
449
450 void
451 i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
452 {
453   struct gdbarch *gdbarch = get_regcache_arch (regcache);
454   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
455   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
456   const gdb_byte *regs = fsave;
457   int i;
458
459   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
460
461   for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
462     if (regnum == -1 || regnum == i)
463       {
464         if (fsave == NULL)
465           {
466             regcache_raw_supply (regcache, i, NULL);
467             continue;
468           }
469
470         /* Most of the FPU control registers occupy only 16 bits in the
471            fsave area.  Give those a special treatment.  */
472         if (i >= I387_FCTRL_REGNUM (tdep)
473             && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
474           {
475             gdb_byte val[4];
476
477             memcpy (val, FSAVE_ADDR (tdep, regs, i), 2);
478             val[2] = val[3] = 0;
479             if (i == I387_FOP_REGNUM (tdep))
480               val[1] &= ((1 << 3) - 1);
481             regcache_raw_supply (regcache, i, val);
482           }
483         else
484           regcache_raw_supply (regcache, i, FSAVE_ADDR (tdep, regs, i));
485       }
486
487   /* Provide dummy values for the SSE registers.  */
488   for (i = I387_XMM0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
489     if (regnum == -1 || regnum == i)
490       regcache_raw_supply (regcache, i, NULL);
491   if (regnum == -1 || regnum == I387_MXCSR_REGNUM (tdep))
492     {
493       gdb_byte buf[4];
494
495       store_unsigned_integer (buf, 4, byte_order, 0x1f80);
496       regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), buf);
497     }
498 }
499
500 /* Fill register REGNUM (if it is a floating-point register) in *FSAVE
501    with the value from REGCACHE.  If REGNUM is -1, do this for all
502    registers.  This function doesn't touch any of the reserved bits in
503    *FSAVE.  */
504
505 void
506 i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
507 {
508   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
509   gdb_byte *regs = fsave;
510   int i;
511
512   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
513
514   for (i = I387_ST0_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
515     if (regnum == -1 || regnum == i)
516       {
517         /* Most of the FPU control registers occupy only 16 bits in
518            the fsave area.  Give those a special treatment.  */
519         if (i >= I387_FCTRL_REGNUM (tdep)
520             && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
521           {
522             gdb_byte buf[4];
523
524             regcache_raw_collect (regcache, i, buf);
525
526             if (i == I387_FOP_REGNUM (tdep))
527               {
528                 /* The opcode occupies only 11 bits.  Make sure we
529                    don't touch the other bits.  */
530                 buf[1] &= ((1 << 3) - 1);
531                 buf[1] |= ((FSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
532               }
533             memcpy (FSAVE_ADDR (tdep, regs, i), buf, 2);
534           }
535         else
536           regcache_raw_collect (regcache, i, FSAVE_ADDR (tdep, regs, i));
537       }
538 }
539 \f
540
541 /* At fxsave_offset[REGNUM] you'll find the offset to the location in
542    the data structure used by the "fxsave" instruction where GDB
543    register REGNUM is stored.  */
544
545 static int fxsave_offset[] =
546 {
547   32,                           /* %st(0) through ...  */
548   48,
549   64,
550   80,
551   96,
552   112,
553   128,
554   144,                          /* ... %st(7) (80 bits each).  */
555   0,                            /* `fctrl' (16 bits).  */
556   2,                            /* `fstat' (16 bits).  */
557   4,                            /* `ftag' (16 bits).  */
558   12,                           /* `fiseg' (16 bits).  */
559   8,                            /* `fioff'.  */
560   20,                           /* `foseg' (16 bits).  */
561   16,                           /* `fooff'.  */
562   6,                            /* `fop' (bottom 11 bits).  */
563   160 + 0 * 16,                 /* %xmm0 through ...  */
564   160 + 1 * 16,
565   160 + 2 * 16,
566   160 + 3 * 16,
567   160 + 4 * 16,
568   160 + 5 * 16,
569   160 + 6 * 16,
570   160 + 7 * 16,
571   160 + 8 * 16,
572   160 + 9 * 16,
573   160 + 10 * 16,
574   160 + 11 * 16,
575   160 + 12 * 16,
576   160 + 13 * 16,
577   160 + 14 * 16,
578   160 + 15 * 16,                /* ... %xmm15 (128 bits each).  */
579 };
580
581 #define FXSAVE_ADDR(tdep, fxsave, regnum) \
582   (fxsave + fxsave_offset[regnum - I387_ST0_REGNUM (tdep)])
583
584 /* We made an unfortunate choice in putting %mxcsr after the SSE
585    registers %xmm0-%xmm7 instead of before, since it makes supporting
586    the registers %xmm8-%xmm15 on AMD64 a bit involved.  Therefore we
587    don't include the offset for %mxcsr here above.  */
588
589 #define FXSAVE_MXCSR_ADDR(fxsave) (fxsave + 24)
590
591 static int i387_tag (const gdb_byte *raw);
592 \f
593
594 /* Fill register REGNUM in REGCACHE with the appropriate
595    floating-point or SSE register value from *FXSAVE.  This function
596    masks off any of the reserved bits in *FXSAVE.  */
597
598 void
599 i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
600 {
601   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
602   const gdb_byte *regs = fxsave;
603   int i;
604
605   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
606   gdb_assert (tdep->num_xmm_regs > 0);
607
608   for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
609     if (regnum == -1 || regnum == i)
610       {
611         if (regs == NULL)
612           {
613             regcache_raw_supply (regcache, i, NULL);
614             continue;
615           }
616
617         /* Most of the FPU control registers occupy only 16 bits in
618            the fxsave area.  Give those a special treatment.  */
619         if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
620             && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
621           {
622             gdb_byte val[4];
623
624             memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
625             val[2] = val[3] = 0;
626             if (i == I387_FOP_REGNUM (tdep))
627               val[1] &= ((1 << 3) - 1);
628             else if (i== I387_FTAG_REGNUM (tdep))
629               {
630                 /* The fxsave area contains a simplified version of
631                    the tag word.  We have to look at the actual 80-bit
632                    FP data to recreate the traditional i387 tag word.  */
633
634                 unsigned long ftag = 0;
635                 int fpreg;
636                 int top;
637
638                 top = ((FXSAVE_ADDR (tdep, regs,
639                                      I387_FSTAT_REGNUM (tdep)))[1] >> 3);
640                 top &= 0x7;
641
642                 for (fpreg = 7; fpreg >= 0; fpreg--)
643                   {
644                     int tag;
645
646                     if (val[0] & (1 << fpreg))
647                       {
648                         int thisreg = (fpreg + 8 - top) % 8 
649                                        + I387_ST0_REGNUM (tdep);
650                         tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
651                       }
652                     else
653                       tag = 3;          /* Empty */
654
655                     ftag |= tag << (2 * fpreg);
656                   }
657                 val[0] = ftag & 0xff;
658                 val[1] = (ftag >> 8) & 0xff;
659               }
660             regcache_raw_supply (regcache, i, val);
661           }
662         else
663           regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
664       }
665
666   if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
667     {
668       if (regs == NULL)
669         regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep), NULL);
670       else
671         regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
672                              FXSAVE_MXCSR_ADDR (regs));
673     }
674 }
675
676 /* Fill register REGNUM (if it is a floating-point or SSE register) in
677    *FXSAVE with the value from REGCACHE.  If REGNUM is -1, do this for
678    all registers.  This function doesn't touch any of the reserved
679    bits in *FXSAVE.  */
680
681 void
682 i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
683 {
684   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
685   gdb_byte *regs = fxsave;
686   int i;
687
688   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
689   gdb_assert (tdep->num_xmm_regs > 0);
690
691   for (i = I387_ST0_REGNUM (tdep); i < I387_MXCSR_REGNUM (tdep); i++)
692     if (regnum == -1 || regnum == i)
693       {
694         /* Most of the FPU control registers occupy only 16 bits in
695            the fxsave area.  Give those a special treatment.  */
696         if (i >= I387_FCTRL_REGNUM (tdep) && i < I387_XMM0_REGNUM (tdep)
697             && i != I387_FIOFF_REGNUM (tdep) && i != I387_FOOFF_REGNUM (tdep))
698           {
699             gdb_byte buf[4];
700
701             regcache_raw_collect (regcache, i, buf);
702
703             if (i == I387_FOP_REGNUM (tdep))
704               {
705                 /* The opcode occupies only 11 bits.  Make sure we
706                    don't touch the other bits.  */
707                 buf[1] &= ((1 << 3) - 1);
708                 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
709               }
710             else if (i == I387_FTAG_REGNUM (tdep))
711               {
712                 /* Converting back is much easier.  */
713
714                 unsigned short ftag;
715                 int fpreg;
716
717                 ftag = (buf[1] << 8) | buf[0];
718                 buf[0] = 0;
719                 buf[1] = 0;
720
721                 for (fpreg = 7; fpreg >= 0; fpreg--)
722                   {
723                     int tag = (ftag >> (fpreg * 2)) & 3;
724
725                     if (tag != 3)
726                       buf[0] |= (1 << fpreg);
727                   }
728               }
729             memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
730           }
731         else
732           regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
733       }
734
735   if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
736     regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
737                           FXSAVE_MXCSR_ADDR (regs));
738 }
739
740 /* `xstate_bv' is at byte offset 512.  */
741 #define XSAVE_XSTATE_BV_ADDR(xsave) (xsave + 512)
742
743 /* At xsave_avxh_offset[REGNUM] you'll find the offset to the location in
744    the upper 128bit of AVX register data structure used by the "xsave"
745    instruction where GDB register REGNUM is stored.  */
746
747 static int xsave_avxh_offset[] =
748 {
749   576 + 0 * 16,         /* Upper 128bit of %ymm0 through ...  */
750   576 + 1 * 16,
751   576 + 2 * 16,
752   576 + 3 * 16,
753   576 + 4 * 16,
754   576 + 5 * 16,
755   576 + 6 * 16,
756   576 + 7 * 16,
757   576 + 8 * 16,
758   576 + 9 * 16,
759   576 + 10 * 16,
760   576 + 11 * 16,
761   576 + 12 * 16,
762   576 + 13 * 16,
763   576 + 14 * 16,
764   576 + 15 * 16         /* Upper 128bit of ... %ymm15 (128 bits each).  */
765 };
766
767 #define XSAVE_AVXH_ADDR(tdep, xsave, regnum) \
768   (xsave + xsave_avxh_offset[regnum - I387_YMM0H_REGNUM (tdep)])
769
770 /* Similar to i387_supply_fxsave, but use XSAVE extended state.  */
771
772 void
773 i387_supply_xsave (struct regcache *regcache, int regnum,
774                    const void *xsave)
775 {
776   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
777   const gdb_byte *regs = xsave;
778   int i;
779   unsigned int clear_bv;
780   static const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };
781   enum
782     {
783       none = 0x0,
784       x87 = 0x1,
785       sse = 0x2,
786       avxh = 0x4,
787       all = x87 | sse | avxh
788     } regclass;
789
790   gdb_assert (regs != NULL);
791   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
792   gdb_assert (tdep->num_xmm_regs > 0);
793
794   if (regnum == -1)
795     regclass = all;
796   else if (regnum >= I387_YMM0H_REGNUM (tdep)
797            && regnum < I387_YMMENDH_REGNUM (tdep))
798     regclass = avxh;
799   else if (regnum >= I387_XMM0_REGNUM(tdep)
800            && regnum < I387_MXCSR_REGNUM (tdep))
801     regclass = sse;
802   else if (regnum >= I387_ST0_REGNUM (tdep)
803            && regnum < I387_FCTRL_REGNUM (tdep))
804     regclass = x87;
805   else
806     regclass = none;
807
808   if (regclass != none)
809     {
810       /* Get `xstat_bv'.  */
811       const gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
812
813       /* The supported bits in `xstat_bv' are 1 byte.  Clear part in
814          vector registers if its bit in xstat_bv is zero.  */
815       clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
816     }
817   else
818     clear_bv = I386_XSTATE_AVX_MASK;
819
820   /* With the delayed xsave mechanism, in between the program
821      starting, and the program accessing the vector registers for the
822      first time, the register's values are invalid.  The kernel
823      initializes register states to zero when they are set the first
824      time in a program.  This means that from the user-space programs'
825      perspective, it's the same as if the registers have always been
826      zero from the start of the program.  Therefore, the debugger
827      should provide the same illusion to the user.  */
828
829   switch (regclass)
830     {
831     case none:
832       break;
833
834     case avxh:
835       if ((clear_bv & I386_XSTATE_AVX))
836         regcache_raw_supply (regcache, regnum, zero);
837       else
838         regcache_raw_supply (regcache, regnum,
839                              XSAVE_AVXH_ADDR (tdep, regs, regnum));
840       return;
841
842     case sse:
843       if ((clear_bv & I386_XSTATE_SSE))
844         regcache_raw_supply (regcache, regnum, zero);
845       else
846         regcache_raw_supply (regcache, regnum,
847                              FXSAVE_ADDR (tdep, regs, regnum));
848       return;
849
850     case x87:
851       if ((clear_bv & I386_XSTATE_X87))
852         regcache_raw_supply (regcache, regnum, zero);
853       else
854         regcache_raw_supply (regcache, regnum,
855                              FXSAVE_ADDR (tdep, regs, regnum));
856       return;
857
858     case all:
859       /* Handle the upper YMM registers.  */
860       if ((tdep->xcr0 & I386_XSTATE_AVX))
861         {
862           if ((clear_bv & I386_XSTATE_AVX))
863             {
864               for (i = I387_YMM0H_REGNUM (tdep);
865                    i < I387_YMMENDH_REGNUM (tdep);
866                    i++)
867                 regcache_raw_supply (regcache, i, zero);
868             }
869           else
870             {
871               for (i = I387_YMM0H_REGNUM (tdep);
872                    i < I387_YMMENDH_REGNUM (tdep);
873                    i++)
874                 regcache_raw_supply (regcache, i,
875                                      XSAVE_AVXH_ADDR (tdep, regs, i));
876             }
877         }
878
879       /* Handle the XMM registers.  */
880       if ((tdep->xcr0 & I386_XSTATE_SSE))
881         {
882           if ((clear_bv & I386_XSTATE_SSE))
883             {
884               for (i = I387_XMM0_REGNUM (tdep);
885                    i < I387_MXCSR_REGNUM (tdep);
886                    i++)
887                 regcache_raw_supply (regcache, i, zero);
888             }
889           else
890             {
891               for (i = I387_XMM0_REGNUM (tdep);
892                    i < I387_MXCSR_REGNUM (tdep); i++)
893                 regcache_raw_supply (regcache, i,
894                                      FXSAVE_ADDR (tdep, regs, i));
895             }
896         }
897
898       /* Handle the x87 registers.  */
899       if ((tdep->xcr0 & I386_XSTATE_X87))
900         {
901           if ((clear_bv & I386_XSTATE_X87))
902             {
903               for (i = I387_ST0_REGNUM (tdep);
904                    i < I387_FCTRL_REGNUM (tdep);
905                    i++)
906                 regcache_raw_supply (regcache, i, zero);
907             }
908           else
909             {
910               for (i = I387_ST0_REGNUM (tdep);
911                    i < I387_FCTRL_REGNUM (tdep);
912                    i++)
913                 regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
914             }
915         }
916       break;
917     }
918
919   /* Only handle x87 control registers.  */
920   for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
921     if (regnum == -1 || regnum == i)
922       {
923         /* Most of the FPU control registers occupy only 16 bits in
924            the xsave extended state.  Give those a special treatment.  */
925         if (i != I387_FIOFF_REGNUM (tdep)
926             && i != I387_FOOFF_REGNUM (tdep))
927           {
928             gdb_byte val[4];
929
930             memcpy (val, FXSAVE_ADDR (tdep, regs, i), 2);
931             val[2] = val[3] = 0;
932             if (i == I387_FOP_REGNUM (tdep))
933               val[1] &= ((1 << 3) - 1);
934             else if (i== I387_FTAG_REGNUM (tdep))
935               {
936                 /* The fxsave area contains a simplified version of
937                    the tag word.  We have to look at the actual 80-bit
938                    FP data to recreate the traditional i387 tag word.  */
939
940                 unsigned long ftag = 0;
941                 int fpreg;
942                 int top;
943
944                 top = ((FXSAVE_ADDR (tdep, regs,
945                                      I387_FSTAT_REGNUM (tdep)))[1] >> 3);
946                 top &= 0x7;
947
948                 for (fpreg = 7; fpreg >= 0; fpreg--)
949                   {
950                     int tag;
951
952                     if (val[0] & (1 << fpreg))
953                       {
954                         int thisreg = (fpreg + 8 - top) % 8 
955                                        + I387_ST0_REGNUM (tdep);
956                         tag = i387_tag (FXSAVE_ADDR (tdep, regs, thisreg));
957                       }
958                     else
959                       tag = 3;          /* Empty */
960
961                     ftag |= tag << (2 * fpreg);
962                   }
963                 val[0] = ftag & 0xff;
964                 val[1] = (ftag >> 8) & 0xff;
965               }
966             regcache_raw_supply (regcache, i, val);
967           }
968         else 
969           regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
970       }
971
972   if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
973     regcache_raw_supply (regcache, I387_MXCSR_REGNUM (tdep),
974                          FXSAVE_MXCSR_ADDR (regs));
975 }
976
977 /* Similar to i387_collect_fxsave, but use XSAVE extended state.  */
978
979 void
980 i387_collect_xsave (const struct regcache *regcache, int regnum,
981                     void *xsave, int gcore)
982 {
983   struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
984   gdb_byte *regs = xsave;
985   int i;
986   enum
987     {
988       none = 0x0,
989       check = 0x1,
990       x87 = 0x2 | check,
991       sse = 0x4 | check,
992       avxh = 0x8 | check,
993       all = x87 | sse | avxh
994     } regclass;
995
996   gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
997   gdb_assert (tdep->num_xmm_regs > 0);
998
999   if (regnum == -1)
1000     regclass = all;
1001   else if (regnum >= I387_YMM0H_REGNUM (tdep)
1002            && regnum < I387_YMMENDH_REGNUM (tdep))
1003     regclass = avxh;
1004   else if (regnum >= I387_XMM0_REGNUM(tdep)
1005            && regnum < I387_MXCSR_REGNUM (tdep))
1006     regclass = sse;
1007   else if (regnum >= I387_ST0_REGNUM (tdep)
1008            && regnum < I387_FCTRL_REGNUM (tdep))
1009     regclass = x87;
1010   else
1011     regclass = none;
1012
1013   if (gcore)
1014     {
1015       /* Clear XSAVE extended state.  */
1016       memset (regs, 0, I386_XSTATE_SIZE (tdep->xcr0));
1017
1018       /* Update XCR0 and `xstate_bv' with XCR0 for gcore.  */
1019       if (tdep->xsave_xcr0_offset != -1)
1020         memcpy (regs + tdep->xsave_xcr0_offset, &tdep->xcr0, 8);
1021       memcpy (XSAVE_XSTATE_BV_ADDR (regs), &tdep->xcr0, 8);
1022     }
1023
1024   if ((regclass & check))
1025     {
1026       gdb_byte raw[I386_MAX_REGISTER_SIZE];
1027       gdb_byte *xstate_bv_p = XSAVE_XSTATE_BV_ADDR (regs);
1028       unsigned int xstate_bv = 0;
1029       /* The supported bits in `xstat_bv' are 1 byte.  */
1030       unsigned int clear_bv = (~(*xstate_bv_p)) & tdep->xcr0;
1031       gdb_byte *p;
1032
1033       /* Clear register set if its bit in xstat_bv is zero.  */
1034       if (clear_bv)
1035         {
1036           if ((clear_bv & I386_XSTATE_AVX))
1037             for (i = I387_YMM0H_REGNUM (tdep);
1038                  i < I387_YMMENDH_REGNUM (tdep); i++)
1039               memset (XSAVE_AVXH_ADDR (tdep, regs, i), 0, 16);
1040
1041           if ((clear_bv & I386_XSTATE_SSE))
1042             for (i = I387_XMM0_REGNUM (tdep);
1043                  i < I387_MXCSR_REGNUM (tdep); i++)
1044               memset (FXSAVE_ADDR (tdep, regs, i), 0, 16);
1045
1046           if ((clear_bv & I386_XSTATE_X87))
1047             for (i = I387_ST0_REGNUM (tdep);
1048                  i < I387_FCTRL_REGNUM (tdep); i++)
1049               memset (FXSAVE_ADDR (tdep, regs, i), 0, 10);
1050         }
1051
1052       if (regclass == all)
1053         {
1054           /* Check if any upper YMM registers are changed.  */
1055           if ((tdep->xcr0 & I386_XSTATE_AVX))
1056             for (i = I387_YMM0H_REGNUM (tdep);
1057                  i < I387_YMMENDH_REGNUM (tdep); i++)
1058               {
1059                 regcache_raw_collect (regcache, i, raw);
1060                 p = XSAVE_AVXH_ADDR (tdep, regs, i);
1061                 if (memcmp (raw, p, 16))
1062                   {
1063                     xstate_bv |= I386_XSTATE_AVX;
1064                     memcpy (p, raw, 16);
1065                   }
1066               }
1067
1068           /* Check if any SSE registers are changed.  */
1069           if ((tdep->xcr0 & I386_XSTATE_SSE))
1070             for (i = I387_XMM0_REGNUM (tdep);
1071                  i < I387_MXCSR_REGNUM (tdep); i++)
1072               {
1073                 regcache_raw_collect (regcache, i, raw);
1074                 p = FXSAVE_ADDR (tdep, regs, i);
1075                 if (memcmp (raw, p, 16))
1076                   {
1077                     xstate_bv |= I386_XSTATE_SSE;
1078                     memcpy (p, raw, 16);
1079                   }
1080               }
1081
1082           /* Check if any X87 registers are changed.  */
1083           if ((tdep->xcr0 & I386_XSTATE_X87))
1084             for (i = I387_ST0_REGNUM (tdep);
1085                  i < I387_FCTRL_REGNUM (tdep); i++)
1086               {
1087                 regcache_raw_collect (regcache, i, raw);
1088                 p = FXSAVE_ADDR (tdep, regs, i);
1089                 if (memcmp (raw, p, 10))
1090                   {
1091                     xstate_bv |= I386_XSTATE_X87;
1092                     memcpy (p, raw, 10);
1093                   }
1094               }
1095         }
1096       else
1097         {
1098           /* Check if REGNUM is changed.  */
1099           regcache_raw_collect (regcache, regnum, raw);
1100
1101           switch (regclass)
1102             {
1103             default:
1104               internal_error (__FILE__, __LINE__,
1105                               _("invalid i387 regclass"));
1106
1107             case avxh:
1108               /* This is an upper YMM register.  */
1109               p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
1110               if (memcmp (raw, p, 16))
1111                 {
1112                   xstate_bv |= I386_XSTATE_AVX;
1113                   memcpy (p, raw, 16);
1114                 }
1115               break;
1116
1117             case sse:
1118               /* This is an SSE register.  */
1119               p = FXSAVE_ADDR (tdep, regs, regnum);
1120               if (memcmp (raw, p, 16))
1121                 {
1122                   xstate_bv |= I386_XSTATE_SSE;
1123                   memcpy (p, raw, 16);
1124                 }
1125               break;
1126
1127             case x87:
1128               /* This is an x87 register.  */
1129               p = FXSAVE_ADDR (tdep, regs, regnum);
1130               if (memcmp (raw, p, 10))
1131                 {
1132                   xstate_bv |= I386_XSTATE_X87;
1133                   memcpy (p, raw, 10);
1134                 }
1135               break;
1136             }
1137         }
1138
1139       /* Update the corresponding bits in `xstate_bv' if any SSE/AVX
1140          registers are changed.  */
1141       if (xstate_bv)
1142         {
1143           /* The supported bits in `xstat_bv' are 1 byte.  */
1144           *xstate_bv_p |= (gdb_byte) xstate_bv;
1145
1146           switch (regclass)
1147             {
1148             default:
1149               internal_error (__FILE__, __LINE__,
1150                               _("invalid i387 regclass"));
1151
1152             case all:
1153               break;
1154
1155             case x87:
1156             case sse:
1157             case avxh:
1158               /* Register REGNUM has been updated.  Return.  */
1159               return;
1160             }
1161         }
1162       else
1163         {
1164           /* Return if REGNUM isn't changed.  */
1165           if (regclass != all)
1166             return;
1167         }
1168     }
1169
1170   /* Only handle x87 control registers.  */
1171   for (i = I387_FCTRL_REGNUM (tdep); i < I387_XMM0_REGNUM (tdep); i++)
1172     if (regnum == -1 || regnum == i)
1173       {
1174         /* Most of the FPU control registers occupy only 16 bits in
1175            the xsave extended state.  Give those a special treatment.  */
1176         if (i != I387_FIOFF_REGNUM (tdep)
1177             && i != I387_FOOFF_REGNUM (tdep))
1178           {
1179             gdb_byte buf[4];
1180
1181             regcache_raw_collect (regcache, i, buf);
1182
1183             if (i == I387_FOP_REGNUM (tdep))
1184               {
1185                 /* The opcode occupies only 11 bits.  Make sure we
1186                    don't touch the other bits.  */
1187                 buf[1] &= ((1 << 3) - 1);
1188                 buf[1] |= ((FXSAVE_ADDR (tdep, regs, i))[1] & ~((1 << 3) - 1));
1189               }
1190             else if (i == I387_FTAG_REGNUM (tdep))
1191               {
1192                 /* Converting back is much easier.  */
1193
1194                 unsigned short ftag;
1195                 int fpreg;
1196
1197                 ftag = (buf[1] << 8) | buf[0];
1198                 buf[0] = 0;
1199                 buf[1] = 0;
1200
1201                 for (fpreg = 7; fpreg >= 0; fpreg--)
1202                   {
1203                     int tag = (ftag >> (fpreg * 2)) & 3;
1204
1205                     if (tag != 3)
1206                       buf[0] |= (1 << fpreg);
1207                   }
1208               }
1209             memcpy (FXSAVE_ADDR (tdep, regs, i), buf, 2);
1210           }
1211         else
1212           regcache_raw_collect (regcache, i, FXSAVE_ADDR (tdep, regs, i));
1213       }
1214
1215   if (regnum == I387_MXCSR_REGNUM (tdep) || regnum == -1)
1216     regcache_raw_collect (regcache, I387_MXCSR_REGNUM (tdep),
1217                           FXSAVE_MXCSR_ADDR (regs));
1218 }
1219
1220 /* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
1221    *RAW.  */
1222
1223 static int
1224 i387_tag (const gdb_byte *raw)
1225 {
1226   int integer;
1227   unsigned int exponent;
1228   unsigned long fraction[2];
1229
1230   integer = raw[7] & 0x80;
1231   exponent = (((raw[9] & 0x7f) << 8) | raw[8]);
1232   fraction[0] = ((raw[3] << 24) | (raw[2] << 16) | (raw[1] << 8) | raw[0]);
1233   fraction[1] = (((raw[7] & 0x7f) << 24) | (raw[6] << 16)
1234                  | (raw[5] << 8) | raw[4]);
1235
1236   if (exponent == 0x7fff)
1237     {
1238       /* Special.  */
1239       return (2);
1240     }
1241   else if (exponent == 0x0000)
1242     {
1243       if (fraction[0] == 0x0000 && fraction[1] == 0x0000 && !integer)
1244         {
1245           /* Zero.  */
1246           return (1);
1247         }
1248       else
1249         {
1250           /* Special.  */
1251           return (2);
1252         }
1253     }
1254   else
1255     {
1256       if (integer)
1257         {
1258           /* Valid.  */
1259           return (0);
1260         }
1261       else
1262         {
1263           /* Special.  */
1264           return (2);
1265         }
1266     }
1267 }
1268
1269 /* Prepare the FPU stack in REGCACHE for a function return.  */
1270
1271 void
1272 i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
1273 {
1274   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1275   ULONGEST fstat;
1276
1277   /* Set the top of the floating-point register stack to 7.  The
1278      actual value doesn't really matter, but 7 is what a normal
1279      function return would end up with if the program started out with
1280      a freshly initialized FPU.  */
1281   regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM (tdep), &fstat);
1282   fstat |= (7 << 11);
1283   regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM (tdep), fstat);
1284
1285   /* Mark %st(1) through %st(7) as empty.  Since we set the top of the
1286      floating-point register stack to 7, the appropriate value for the
1287      tag word is 0x3fff.  */
1288   regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM (tdep), 0x3fff);
1289
1290 }