This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: [avr-gcc-list] tool chain bug (fwd)
- From: "Theodore A. Roth" <troth at verinet dot com>
- To: Alan Modra <amodra at bigpond dot net dot au>
- Cc: binutils at sources dot redhat dot com, Marek Michalkiewicz <marekm at amelek dot gda dot pl>, Denis Chertykov <denisc at overta dot ru>
- Date: Thu, 26 Sep 2002 09:18:15 -0700 (PDT)
- Subject: 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