This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]