Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Jim Blandy <jimb@cygnus.com>
To: "Ben Combee" <bcombee@metrowerks.com>
Cc: <egcs@egcs.cygnus.com>, <gdb@sourceware.cygnus.com>
Subject: Re: IA32: printing FP register variables
Date: Fri, 09 Jul 1999 13:50:00 -0000	[thread overview]
Message-ID: <npbtdlsg2i.fsf@zwingli.cygnus.com> (raw)
In-Reply-To: <00d401beca31$3d752c10$3404010a@metrowerks.com>

I'm sorry, Ben, but I'm still confused about how you find the FP
register containing a variable.  I think there's a fundamental,
difficult problem here which you don't seem to be mentioning at all.
Perhaps you have solved it already, and assume we have too.

In code generated by your compiler, is the value of TOP (the three-bit
FPU stack pointer) at function entry known at compile time?  Or does
its value depend on the caller, and the caller's caller, etc.?

For a function like this:

    double
    dot_product (int n, double *a, double *b)
    {
      int i;
      double sum = 0;

      for (i = 0; i < n; i++)
	sum += a[i] * b[i];

      return sum;
    }

EGCS generates code like this:

    00000000 <dot_product>:
       0:	55             	pushl  %ebp
       1:	31 c0          	xorl   %eax,%eax
       3:	89 e5          	movl   %esp,%ebp
       5:	53             	pushl  %ebx
       6:	8b 5d 08       	movl   0x8(%ebp),%ebx
       9:	d9 ee          	fldz   
       b:	8b 4d 0c       	movl   0xc(%ebp),%ecx
       e:	8b 55 10       	movl   0x10(%ebp),%edx
      11:	39 d8          	cmpl   %ebx,%eax
      13:	7d 18          	jnl    2d <dot_product+0x2d>
      15:	8d 74 26 00    	leal   0x0(%esi,1),%esi
      19:	8d bc 27 00 00 	leal   0x0(%edi,1),%edi
      1e:	00 00 
      20:	dd 04 c1       	fldl   (%ecx,%eax,8)
      23:	dc 0c c2       	fmull  (%edx,%eax,8)
      26:	40             	incl   %eax
      27:	39 d8          	cmpl   %ebx,%eax
      29:	de c1          	faddp  %st,%st(1)
      2b:	7c f3          	jl     20 <dot_product+0x20>
      2d:	5b             	popl   %ebx
      2e:	89 ec          	movl   %ebp,%esp
      30:	5d             	popl   %ebp
      31:	c3             	ret    
      32:	8d b4 26 00 00 	leal   0x0(%esi,1),%esi
      37:	00 00 
      39:	8d bc 27 00 00 	leal   0x0(%edi,1),%edi
      3e:	00 00 

(The bizarre nop leal instructions are generated by the assembler to
get the loop aligned right.  Ignore them.)

The `fldz' at 9 pushes the value of `sum' on the FP stack.  That stack
register is where `sum' lives.  However, since we don't know the value
of TOP upon function entry, we don't know which physical register that
is.  So GCC can't use physical FP register numbers to communicate the
variable's location to GDB.

At different points in the function, the stack will have different
depths.  From b to 20, `sum' is in ST(0).  But at 20 we push a[i] on
the stack, so `sum' is now in ST(1).  At 29 we add the product into
`sum', and pop it off the stack, so from 2b to 31, `sum' is in ST(0)
again.

I should be able to step through this function, one instruction at a
time, and print `sum' correctly at each point.  But whether GDB should
fetch ST(0) or ST(1) depends on where I am in the code.

Note that there is no "frame pointer" for the FP stack.  If I hit a
breakpoint in the middle of the function, GDB has no way of knowing
what TOP was at function entry.

GDB could figure this out by disassembling the instruction stream and
looking for FP instructions, but that's a pain.  GCC always knows how
to find the variables, of course, but it doesn't include its knowledge
in the debug info.
From jimb@cygnus.com Fri Jul 09 13:52:00 1999
From: Jim Blandy <jimb@cygnus.com>
To: "Ben Combee" <bcombee@metrowerks.com>
Cc: <egcs@egcs.cygnus.com>, <gdb@sourceware.cygnus.com>
Subject: Re: IA32: printing FP register variables
Date: Fri, 09 Jul 1999 13:52:00 -0000
Message-id: <npaet5sg0c.fsf@zwingli.cygnus.com>
References: <199907090356.WAA01337@zwingli.cygnus.com> <000d01bec9c2$06f4fdb0$3404010a@metrowerks.com> <np3dyxu2ua.fsf@zwingli.cygnus.com> <014f01beca41$c42b4e50$3404010a@metrowerks.com>
X-SW-Source: 1999-q3/msg00031.html
Content-length: 384

> At each instruction, the invariant that a is 0 from the bottom and b is 1
> from the bottom holds.  Note, the bottom of the stack can be known by the
> debugger via scanning the FPU tag word from the TOP element looking for a FP
> register that is empty.  All this info is provided by an FSAVE or FSTENV.

That could work, but what if you happen to have all eight registers in
use?
From jimb@cygnus.com Fri Jul 09 13:57:00 1999
From: Jim Blandy <jimb@cygnus.com>
To: Joern Rennecke <amylaar@cygnus.co.uk>
Cc: law@cygnus.com, egcs@egcs.cygnus.com, gdb@sourceware.cygnus.com
Subject: Re: IA32: printing FP register variables
Date: Fri, 09 Jul 1999 13:57:00 -0000
Message-id: <np908psfqu.fsf@zwingli.cygnus.com>
References: <199907091822.TAA31184@phal.cygnus.co.uk>
X-SW-Source: 1999-q3/msg00032.html
Content-length: 853

> > STABS's live range splitting notation can certainly do the job
> > correctly, but I wonder whether it can do it efficiently.  For every
> > instruction that changes TOP, you have to start a new range for every
> > variable.  So the size of debug info is O(number of insns * average
> > number of live variables).
> 
> You only have to care about variables that are live in the register stack
> before or after the operation.  So you can use an upper bound of 8.
> Hence the deubg info is O(number of insns).

Okay, but do you really want to emit up to eight stabs at every FP
instruction that changes the stack?

I dunno --- maybe it's not a big deal.  It may not be worth creating a
whole new form of debugging info to save that space.  It is certainly
a problem the various LRS representations handle.  I'd certainly agree
we should try it first.
From bcombee@metrowerks.com Fri Jul 09 14:00:00 1999
From: "Ben Combee" <bcombee@metrowerks.com>
To: "Jim Blandy" <jimb@cygnus.com>
Cc: <egcs@egcs.cygnus.com>, <gdb@sourceware.cygnus.com>
Subject: Re: IA32: printing FP register variables
Date: Fri, 09 Jul 1999 14:00:00 -0000
Message-id: <01cc01beca4d$f76868a0$3404010a@metrowerks.com>
References: <199907090356.WAA01337@zwingli.cygnus.com> <000d01bec9c2$06f4fdb0$3404010a@metrowerks.com> <np3dyxu2ua.fsf@zwingli.cygnus.com> <014f01beca41$c42b4e50$3404010a@metrowerks.com> <npaet5sg0c.fsf@zwingli.cygnus.com>
X-SW-Source: 1999-q3/msg00033.html
Content-length: 999

> > At each instruction, the invariant that a is 0 from the bottom and b is
1
> > from the bottom holds.  Note, the bottom of the stack can be known by
the
> > debugger via scanning the FPU tag word from the TOP element looking for
a FP
> > register that is empty.  All this info is provided by an FSAVE or
FSTENV.
>
> That could work, but what if you happen to have all eight registers in
> use?

Then the scan code sees that there are no empty registers, so the eighth
register is the bottom of the stack.  The IA32 FPU itself uses this logic --
if you push something on the stack such that TOP gets incremented to point
to a non-empty value, you get a stack overflow.

Of course, all this is also based on the assumption, explicit in the Win32
ABI, that the FPU stack is empty on entry to a function.  I think this holds
for the x86 Linux ABI as well -- I can't see any logical other way to do it
since you don't generally know how many levels of nesting there are when
your function is called.


  parent reply	other threads:[~1999-07-09 13:50 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <199907091724.SAA31114@phal.cygnus.co.uk>
     [not found] ` <00d401beca31$3d752c10$3404010a@metrowerks.com>
1999-07-09 10:52   ` Jeffrey A Law
1999-07-09 13:50   ` Jim Blandy [this message]
     [not found] <9500.931826533@upchuck.cygnus.com>
     [not found] ` <np1zeci6tm.fsf@zwingli.cygnus.com>
     [not found]   ` <npn1ws2xp1.fsf@zwingli.cygnus.com>
1999-07-19 23:41     ` Richard Henderson
1999-07-26 11:43       ` Jim Blandy
1999-07-26 13:15         ` Richard Henderson
     [not found] <400.931648196@upchuck.cygnus.com>
     [not found] ` <np908ljwht.fsf@zwingli.cygnus.com>
     [not found]   ` <9209.931822541@upchuck.cygnus.com>
1999-07-12 16:50     ` Joern Rennecke
1999-07-12 17:18     ` Robert Lipe
1999-07-12 19:40   ` Richard Henderson
     [not found]     ` <np3dysi9gh.fsf@zwingli.cygnus.com>
1999-07-13 16:05       ` Richard Henderson
1999-07-09 14:00 Michael Meissner
  -- strict thread matches above, loose matches on Subject: below --
1999-07-08 20:56 Jim Blandy
     [not found] ` <000d01bec9c2$06f4fdb0$3404010a@metrowerks.com>
1999-07-08 22:04   ` Jeffrey A Law
1999-07-09  7:04     ` Michael Meissner
1999-07-10 11:00       ` Tom Tromey
1999-07-09 10:53   ` Jim Blandy
1999-07-08 22:12 ` Jeffrey A Law

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=npbtdlsg2i.fsf@zwingli.cygnus.com \
    --to=jimb@cygnus.com \
    --cc=bcombee@metrowerks.com \
    --cc=egcs@egcs.cygnus.com \
    --cc=gdb@sourceware.cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox