/* Intel 387 floating point stuff.
Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
- 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
print_i387_status_word (unsigned int status, struct ui_file *file)
{
fprintf_filtered (file, "Status Word: %s",
- local_hex_string_custom (status, "04"));
+ hex_string_custom (status, 4));
fputs_filtered (" ", file);
fprintf_filtered (file, " %s", (status & 0x0001) ? "IE" : " ");
fprintf_filtered (file, " %s", (status & 0x0002) ? "DE" : " ");
print_i387_control_word (unsigned int control, struct ui_file *file)
{
fprintf_filtered (file, "Control Word: %s",
- local_hex_string_custom (control, "04"));
+ hex_string_custom (control, 4));
fputs_filtered (" ", file);
fprintf_filtered (file, " %s", (control & 0x0001) ? "IM" : " ");
fprintf_filtered (file, " %s", (control & 0x0002) ? "DM" : " ");
print_i387_status_word (fstat, file);
print_i387_control_word (fctrl, file);
fprintf_filtered (file, "Tag Word: %s\n",
- local_hex_string_custom (ftag, "04"));
+ hex_string_custom (ftag, 4));
fprintf_filtered (file, "Instruction Pointer: %s:",
- local_hex_string_custom (fiseg, "02"));
- fprintf_filtered (file, "%s\n", local_hex_string_custom (fioff, "08"));
+ hex_string_custom (fiseg, 2));
+ fprintf_filtered (file, "%s\n", hex_string_custom (fioff, 8));
fprintf_filtered (file, "Operand Pointer: %s:",
- local_hex_string_custom (foseg, "02"));
- fprintf_filtered (file, "%s\n", local_hex_string_custom (fooff, "08"));
+ hex_string_custom (foseg, 2));
+ fprintf_filtered (file, "%s\n", hex_string_custom (fooff, 8));
fprintf_filtered (file, "Opcode: %s\n",
- local_hex_string_custom (fop ? (fop | 0xd800) : 0, "04"));
+ hex_string_custom (fop ? (fop | 0xd800) : 0, 4));
#undef I387_ST0_REGNUM
}
/* We only support floating-point values. */
if (TYPE_CODE (type) != TYPE_CODE_FLT)
{
- warning ("Cannot convert floating-point register value "
- "to non-floating-point type.");
+ warning (_("Cannot convert floating-point register value "
+ "to non-floating-point type."));
return;
}
/* We only support floating-point values. */
if (TYPE_CODE (type) != TYPE_CODE_FLT)
{
- warning ("Cannot convert non-floating-point type "
- "to floating-point register value.");
+ warning (_("Cannot convert non-floating-point type "
+ "to floating-point register value."));
return;
}
put_frame_register (frame, regnum, to);
}
\f
-\f
/* Handle FSAVE and FXSAVE formats. */
(fsave + fsave_offset[regnum - I387_ST0_REGNUM])
\f
-/* Fill register REGNUM in GDB's register cache with the appropriate
- value from *FSAVE. This function masks off any of the reserved
- bits in *FSAVE. */
+/* Fill register REGNUM in REGCACHE with the appropriate value from
+ *FSAVE. This function masks off any of the reserved bits in
+ *FSAVE. */
void
-i387_supply_fsave (const void *fsave, int regnum)
+i387_supply_fsave (struct regcache *regcache, int regnum, const void *fsave)
{
- struct regcache *regcache = current_regcache;
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
const char *regs = fsave;
int i;
gdb_assert (tdep->st0_regnum >= I386_ST0_REGNUM);
- /* Define I387_ST0_REGNUM such that we use the proper definitions
- for REGCACHE's architecture. */
+ /* Define I387_ST0_REGNUM and I387_NUM_XMM_REGS such that we use the
+ proper definitions for REGCACHE's architecture. */
+
#define I387_ST0_REGNUM tdep->st0_regnum
+#define I387_NUM_XMM_REGS tdep->num_xmm_regs
for (i = I387_ST0_REGNUM; i < I387_XMM0_REGNUM; i++)
if (regnum == -1 || regnum == i)
else
regcache_raw_supply (regcache, i, FSAVE_ADDR (regs, i));
}
+
+ /* Provide dummy values for the SSE registers. */
+ for (i = I387_XMM0_REGNUM; i < I387_MXCSR_REGNUM; i++)
+ if (regnum == -1 || regnum == i)
+ regcache_raw_supply (regcache, i, NULL);
+ if (regnum == -1 || regnum == I387_MXCSR_REGNUM)
+ {
+ char buf[4];
+
+ store_unsigned_integer (buf, 4, 0x1f80);
+ regcache_raw_supply (regcache, I387_MXCSR_REGNUM, buf);
+ }
+
#undef I387_ST0_REGNUM
+#undef I387_NUM_XMM_REGS
}
/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
- with the value in GDB's register cache. If REGNUM is -1, do this
- for all registers. This function doesn't touch any of the reserved
- bits in *FSAVE. */
+ with the value from REGCACHE. If REGNUM is -1, do this for all
+ registers. This function doesn't touch any of the reserved bits in
+ *FSAVE. */
void
-i387_fill_fsave (void *fsave, int regnum)
+i387_collect_fsave (const struct regcache *regcache, int regnum, void *fsave)
{
- struct regcache *regcache = current_regcache;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
char *regs = fsave;
int i;
}
#undef I387_ST0_REGNUM
}
+
+/* Fill register REGNUM (if it is a floating-point register) in *FSAVE
+ with the value in GDB's register cache. If REGNUM is -1, do this
+ for all registers. This function doesn't touch any of the reserved
+ bits in *FSAVE. */
+
+void
+i387_fill_fsave (void *fsave, int regnum)
+{
+ i387_collect_fsave (current_regcache, regnum, fsave);
+}
\f
/* At fxsave_offset[REGNUM] you'll find the offset to the location in
static int i387_tag (const unsigned char *raw);
\f
-/* Fill register REGNUM in GDB's register cache with the appropriate
+/* Fill register REGNUM in REGCACHE with the appropriate
floating-point or SSE register value from *FXSAVE. This function
masks off any of the reserved bits in *FXSAVE. */
void
-i387_supply_fxsave (const void *fxsave, int regnum)
+i387_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave)
{
- struct regcache *regcache = current_regcache;
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_regcache_arch (regcache));
const char *regs = fxsave;
int i;
}
/* Fill register REGNUM (if it is a floating-point or SSE register) in
- *FXSAVE with the value in GDB's register cache. If REGNUM is -1, do
- this for all registers. This function doesn't touch any of the
- reserved bits in *FXSAVE. */
+ *FXSAVE with the value from REGCACHE. If REGNUM is -1, do this for
+ all registers. This function doesn't touch any of the reserved
+ bits in *FXSAVE. */
void
-i387_fill_fxsave (void *fxsave, int regnum)
+i387_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave)
{
- struct regcache *regcache = current_regcache;
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
char *regs = fxsave;
int i;
#undef I387_NUM_XMM_REGS
}
+/* Fill register REGNUM (if it is a floating-point or SSE register) in
+ *FXSAVE with the value in GDB's register cache. If REGNUM is -1, do
+ this for all registers. This function doesn't touch any of the
+ reserved bits in *FXSAVE. */
+
+void
+i387_fill_fxsave (void *fxsave, int regnum)
+{
+ i387_collect_fxsave (current_regcache, regnum, fxsave);
+}
+
/* Recreate the FTW (tag word) valid bits from the 80-bit FP data in
*RAW. */
}
}
}
+
+/* Prepare the FPU stack in REGCACHE for a function return. */
+
+void
+i387_return_value (struct gdbarch *gdbarch, struct regcache *regcache)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ ULONGEST fstat;
+
+ /* Define I387_ST0_REGNUM such that we use the proper
+ definitions for the architecture. */
+#define I387_ST0_REGNUM tdep->st0_regnum
+
+ /* Set the top of the floating-point register stack to 7. The
+ actual value doesn't really matter, but 7 is what a normal
+ function return would end up with if the program started out with
+ a freshly initialized FPU. */
+ regcache_raw_read_unsigned (regcache, I387_FSTAT_REGNUM, &fstat);
+ fstat |= (7 << 11);
+ regcache_raw_write_unsigned (regcache, I387_FSTAT_REGNUM, fstat);
+
+ /* Mark %st(1) through %st(7) as empty. Since we set the top of the
+ floating-point register stack to 7, the appropriate value for the
+ tag word is 0x3fff. */
+ regcache_raw_write_unsigned (regcache, I387_FTAG_REGNUM, 0x3fff);
+
+#undef I387_ST0_REGNUM
+}