This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [avr-gcc-list] tool chain bug (fwd)



On Thu, 26 Sep 2002, Alan Modra wrote:

:) On Wed, Sep 25, 2002 at 08:42:59PM -0700, Theodore A. Roth wrote:
:) > [troth@bozoland messy]$ cat mm.s
:) >         .arch atmega128
:) > __SREG__ = 0x3f
:) > __SP_H__ = 0x3e
:) > __SP_L__ = 0x3d
:) > __tmp_reg__ = 0
:) > __zero_reg__ = 1
:) > _PC_ = 2
:) > .Lfoo:
:) >         dec r24
:) >         brne _PC_-4
:) > .Lbar:
:) >         dec r24
:) >         brne .Lbar
:) > .Lloop:
:) >         rjmp .Lloop
:) >
:) > Running this through gas with your patch yields this:
:) >
:) > 00000000 <.text>:
:) >    0:   8a 95           dec     r24
:) >    2:   e9 f7           brne    .-6             ; 0xfffffffe
:) >    4:   8a 95           dec     r24
:) >    6:   f1 f7           brne    .-4             ; 0x4
:) >    8:   ff cf           rjmp    .-2             ; 0x8
:) >
:) > line "2:" should match line "6:".
:)
:) Why?  Or more specifically, what is the meaning of "brne -2"?  The

Maybe this will help. The brne opcode looks like this (binary):

  1111 01kk kkkk k001 where -64 < k < 63

The result of "brne k" if the condition is not equal, is

  PC <- PC + k + 1

Note that , PC is an addr to 16-bit word (insn) whereas the gnu tools only
deal with addr to 8-bit bytes (which is why everything above is 2x).

The "brne _PC_-4" above is something that gcc emits in the asm code it
generates.

The first brne above should be branching to line 0:. The -2 (0xfffffffe)
is just the disassembler giving you the absolute addr of where the branch
is going (addresses can somehow wrap around on the avr).

:) fact that older avr gas assembled this differently doesn't mean much.
:) I reckon the old behaviour was wrong, and that "brne -2" ought to
:) branch to address -2.

You make a good point here. Now that I've thought about this, you may be
right. See below.

:) If you really want a pc relative branch, write "brne .-4"

I just tried this with gas (without your patch):

roth@knuth:~/dev/messy$ cat mm.s
        .arch atmega128
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
_PC_ = 2
        nop
        nop
.Lfoo1:
        dec r24
        brne _PC_-4
.Lfoo2:
        dec r24
        brne .-4
.Lfoo3:
        dec r24
        brne .Lfoo3


Here's what I got:

00000000 <.text>:
   0:   00 00           nop
   2:   00 00           nop
   4:   8a 95           dec     r24
   6:   01 f4           brne    .+0             ; 0x8
   8:   8a 95           dec     r24
   a:   f1 f7           brne    .-4             ; 0x8
   c:   8a 95           dec     r24
   e:   f1 f7           brne    .-4             ; 0xc

I think gas is actually doing the right thing (with respect to your
comment above) and treating "brne _PC_-4" as "brne -2" and thinking -2 is
an absolute addr instead of a pc relative one.

So, this really looks like a bug in gcc which should _not_ be generating
the "brne _PC_-4", but instead using "brne .-4"

If you agree, I'll pursue this with gcc and consider your changes to gas
as "proven" correct.

Thanks for your time.

Ted Roth



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