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
- Date: Wed, 25 Sep 2002 20:42:59 -0700 (PDT)
- Subject: Re: [avr-gcc-list] tool chain bug (fwd)
Alan,
Thanks for the help.
On Thu, 26 Sep 2002, Alan Modra wrote:
:)Heh, large changes get blamed for everything. :) Looking over the
:)part I removed from tc-avr.c again though, I think I may have
:)removed too much. Does the following patch cure your problem?
No. value is wrong coming into md_apply_fix3(). Consider this code snippet:
[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:".
Somehow valP is getting mangled before it gets passed to md_apply_fix3().
I tried adding this ugliness on top of your patch, but alas, it's still
broken:
Index: gas/config/tc-avr.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-avr.c,v
retrieving revision 1.18
diff -u -r1.18 tc-avr.c
--- gas/config/tc-avr.c 5 Sep 2002 00:01:17 -0000 1.18
+++ gas/config/tc-avr.c 26 Sep 2002 03:38:32 -0000
@@ -705,8 +705,11 @@
case 'l':
str = parse_exp (str, &op_expr);
- fix_new_exp (frag_now, where, opcode->insn_size * 2,
- &op_expr, true, BFD_RELOC_AVR_7_PCREL);
+ if (op_expr.X_add_symbol)
+ fix_new_exp (frag_now, where, opcode->insn_size * 2,
+ &op_expr, true, BFD_RELOC_AVR_7_PCREL);
+ else
+ op_mask |= (((op_expr.X_add_number) << 3) & 0x3f8);
break;
case 'i':
Ted Roth
:)
:) * gas/config/tc-avr.c (md_apply_fix3): Reinstate code handling
:) pcrel fixups to current or absolute section.
:)
:)Index: gas/config/tc-avr.c
:)===================================================================
:)RCS file: /cvs/src/src/gas/config/tc-avr.c,v
:)retrieving revision 1.18
:)diff -u -p -r1.18 tc-avr.c
:)--- gas/config/tc-avr.c 5 Sep 2002 00:01:17 -0000 1.18
:)+++ gas/config/tc-avr.c 26 Sep 2002 00:21:55 -0000
:)@@ -838,6 +838,17 @@ md_apply_fix3 (fixP, valP, seg)
:) if (fixP->fx_addsy == (symbolS *) NULL)
:) fixP->fx_done = 1;
:)
:)+ else if (fixP->fx_pcrel)
:)+ {
:)+ segT s = S_GET_SEGMENT (fixP->fx_addsy);
:)+
:)+ if (s == seg || s == absolute_section)
:)+ {
:)+ value += S_GET_VALUE (fixP->fx_addsy);
:)+ fixP->fx_done = 1;
:)+ }
:)+ }
:)+
:) /* We don't actually support subtracting a symbol. */
:) if (fixP->fx_subsy != (symbolS *) NULL)
:) as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
:)
:)
:)> >From what Denis says and my time spent in the debugger, I think that this
:)> fragment from tc-avr.c:
:)>
:)> 706 case 'l':
:)> 707 str = parse_exp (str, &op_expr);
:)> 708 fix_new_exp (frag_now, where, opcode->insn_size * 2,
:)> 709 &op_expr, true, BFD_RELOC_AVR_7_PCREL);
:)> 710 break;
:)> 711
:)>
:)> should probably not be using a fixup and instead just calculate the
:)> op_mask from the pcrel offset and be done with it.
:)
:)I agree.
:)
:)> stage. But, as I remember, I don't support linking of 7-bit PC
:)> relative relocations (BFD_RELOC_AVR_7_PCREL).
:)
:)Especially in light of Denis' comment.
:)
:)