This is the mail archive of the
gdb@sourceware.cygnus.com
mailing list for the GDB project.
Re: MMX: Messy Multimedia eXtensions
> Jim> You can print MMX registers, too, but it's messier, since GDB doesn't
> Jim> know whether it's eight 8-bit values, four 16-bit values, et cetera:
>
> Jim> (gdb) p $mm2
> Jim> $1 = {v8qi = {f = "\001\000\001\000\001\000\001"}, v4hi = {f = {1,
> Jim> 1, 1, 1}}, v2si = {f = {65537, 65537}}, uint64 = 281479271743489}
>
> Jim> (Please ignore the fact that the eight 8-bit integers are printed as
> Jim> characters. I'm going to fix that.)
>
> It appears that the registers are represented by a union or struct.
> Can individual elements be used in GDB expressions? If so, can you
> show how to represent the least significant byte in a mmx register?
> If not, I think this is a very serious deficiency.
Sure, it's a genuine union:
(gdb) p $mm2
$3 = {v8qi = {f = "\001\000\001\000\001\000\001"}, v4hi = {f = {1, 1, 1, 1}},
v2si = {f = {65537, 65537}}, uint64 = 281479271743489}
(gdb) p $mm2.v8qi
$4 = {f = "\001\000\001\000\001\000\001"}
(gdb) p $mm2.v8qi.f[0]
$5 = 1 '\001'
(gdb) set $mm2.v8qi.f[0] = 42
(gdb) p $mm2
$6 = {v8qi = {f = "*\000\001\000\001\000\001"}, v4hi = {f = {42, 1, 1, 1}},
v2si = {f = {65578, 65537}}, uint64 = 281479271743530}
(gdb)
Is that what you wanted to do?
I agree that this is verbose, and I'm open to suggestions. We could
define more register views whose names indicated what interpretation
you want to take. But I'm not sure that $mm2v8qi is so much better
than $mm2.v8qi, and the latter has the advantage that it's guessable
given the results of `print $mm2'. (Or at least, I thought it was.)
> There doesn't appear to be an entry in the MMX union for the single
> precision FP values in AMD's 3DNow extensions. Wearing my GNU hat,
> (rather than my Cygnus-shareholder hat), I'd be very disapointed if
> this got integrated into GDB without AMD 3DNow support even if Intel
> funded Cygnus to do MMX work.
No conspiracy here. It'd be an hour's work, if that, to add 3DNow
register views. Here is all the architecture-specific code for the
MMX regs:
From config/i386/tm-i386.h:
/* GDB provides register views for the MMX registers. */
#define IS_REGISTER_VIEW_NAME i386_is_register_view_name
#define REGISTER_VIEW_NAME(i) (i386_register_view_name[(i)])
#define REGISTER_VIEW_REGNO(i) (i386_register_view_regno[(i)])
#define REGISTER_VIEW_TYPE(i) (i386_register_view_type[(i)])
extern int i386_is_register_view_name (char *name, int len);
extern char *i386_register_view_name[];
extern int i386_register_view_regno[];
extern struct type *i386_register_view_type[];
And from i386-tdep.c:
/* Register views --- providing access to the MMX registers. */
char *i386_register_view_name[] = {
/* The MMX registers. */
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"
};
#define NUM_REGISTER_VIEWS \
(sizeof (i386_register_view_name) \
/ sizeof (i386_register_view_name[0]))
#define FIRST_MMX_VIEW 0
#define LAST_MMX_VIEW 7
int i386_register_view_regno[] = {
FP0_REGNUM + 0, FP0_REGNUM + 1, FP0_REGNUM + 2, FP0_REGNUM + 3,
FP0_REGNUM + 4, FP0_REGNUM + 5, FP0_REGNUM + 6, FP0_REGNUM + 7
};
struct type *i386_register_view_type[NUM_REGISTER_VIEWS];
int
i386_is_register_view_name (char *name, int len)
{
int i;
for (i = 0; i < NUM_REGISTER_VIEWS; i++)
{
/* long variable names suck */
char *view_name = i386_register_view_name[i];
if (len == strlen (view_name)
&& ! memcmp (name, view_name, len))
return i;
}
return -1;
}
static void
init_register_view_types ()
{
/* Construct a type for the MMX registers, and then plug it into the
register view type array. The type we're building is this:
union __builtin_mmx {
struct __builtin_v8qi v8qi;
struct __builtin_v4hi v4hi;
struct __builtin_v2si v2si;
uint64_t uint64;
};
Now stick *that* in your pipeline and smoke it. */
struct type *t;
struct field *f;
int i;
f = (struct field *) xmalloc (sizeof (*f) * 4);
memset (f, 0, sizeof (*f) * 4);
f[0].type = builtin_type_v8qi;
f[0].name = "v8qi";
f[1].type = builtin_type_v4hi;
f[1].name = "v4hi";
f[2].type = builtin_type_v2si;
f[2].name = "v2si";
f[3].type = builtin_type_int64;
f[3].name = "uint64";
/* Build a union type with those fields. */
t = init_type (TYPE_CODE_UNION, 8, 0, 0, 0);
t->nfields = 4;
t->fields = f;
t->tag_name = "__builtin_mmx";
/* Fill in the register view type table with it. */
for (i = FIRST_MMX_VIEW; i <= LAST_MMX_VIEW; i++)
i386_register_view_type[i] = t;
}
To support 3DNow, either extend the __builtin_mmx union, or define a
new type and new view names.