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: IA32: printing FP register variables



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.

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