Subject: Re: mips kernel profiling?
To: Ethan Solomita <ethan@geocast.com>
From: Michael L. Hitch <mhitch@lightning.msu.montana.edu>
List: port-mips
Date: 04/19/2000 21:35:06
On Wed, 19 Apr 2000, Ethan Solomita wrote:

> 	Its day has come! 8-) Unfortunately, it seems like gcc is emitting
> garbage, so either I'm seeing things, or there's something very ugly
> happening here. Here's a partial disassembly of ls_main(), a function in
> the ls command:
...
> 0x400d64 <ls_main+48>:  move    $at,$ra
> 0x400d68 <ls_main+52>:  lw      $t9,-32672($gp)
> 0x400d6c <ls_main+56>:  nop
> 0x400d70 <ls_main+60>:  jalr    $t9
> 0x400d74 <ls_main+64>:  nop
> 0x400d78 <ls_main+68>:  lw      $gp,16($sp)
> 0x400d7c <ls_main+72>:  addiu   $sp,$sp,-8
> 0x400d80 <ls_main+76>:  move    $s1,$a0
> 
> 	This is built with -pg, and the jalr at ls_main+0x60 is the call to
> mcount. Here's what is so confused: normally, it has to do the add -8 to
> $sp, as it does in ls_main+72, *before* the call to mcount()! But it is
> doing it not only after mcount, but also after it reloads $gp from the
> wrong address. So mcount() ends up trampling on 8 bytes of our stack,
> and we reload the wrong location for $gp.
> 
> 	Anyone have any clues why it's doing this???

  I would say that you have an out-of-date compiler.  A little test
program gives me:
  24:   03e00821        move    $at,$ra
  28:   27bdfff8        addiu   $sp,$sp,-8
  2c:   8f990000        lw      $t9,0($gp)
                        2c: R_MIPS_CALL16       _mcount
  30:   00000000        nop
  34:   0320f809        jalr    $t9
  38:   00000000        nop

  The source file generated by cc1 is:
        .set    noreorder
        .set    noat
        move    $1,$31          # save current return address
        subu    $sp,$sp,8               # _mcount pops 2 words from  stack
        jal     _mcount
        nop
        .set    reorder
        .set    at

  As near as I can tell, this should be the case since the 1.4 release.  I
now remember looking into this before, and the problem was fixed over a
year ago.

  What was happening is that egcs was generating the stack adjustment in
the delay slot of the "jal _mcount" instruction.  The problem with this is
that the "delay slot" isn't really a delay slot because gas expands the
"jal _mcount"  'instruction', and the real jal gets generated with a nop
in its delay slot and the stack adjustment came after that nop.  Jonathan
fixed that about 14 months ago to generate the stack adjustment prior to
the "jal _mcount".


--
Michael L. Hitch			mhitch@montana.edu
Computer Consultant
Information Technology Center
Montana State University	Bozeman, MT	USA