Georg-Johann Lay wrote:

> For devices with 8-bit SP reading the high byte SP_H of SP will get garbage.
> 
> The patch uses CLR instead of IN SP_H to "read" the high part of SP.
> 
> There are two issues with this patch:
> 
> == 1 ==
> 
> I cannot really test it because for devices that small running test suite
> does not give usable results.  So I just looked at the patch and the
> small test case like the following compiled
> 
> $ avr-gcc-4.6.2 -Os -mmcu=attiny26 -m[no]call-prologues
> 
> long long a, b;
> 
> long long __attribute__((noinline,noclione))
> bar (char volatile *c)
> {
>     *c = 1;
>     return a+b;
> }
> 
> long long foo()
> {
>     char buf[16];
>     return bar (buf);
> }
> 
> 
> int main (void)
> {
>     return foo();
> }
> 
> 
> The C parts look fine but...
> 
> 
> == 2 ==
> 
> The libgcc parts will still read garbage to R29 as explained in the
> FIXMEs there.
> 
> Solving the FIXMEs can only be achieved by splitting multilibs avr2 and avr25,
> i.e. the mutlilibs that mix devices with/without SP.H, into avr2, avr21, 
> avr24,
> avr25, say.
> 
> I don't think it's a good idea to have real 8-bit SP/FP and that it would 
> cause
> all sorts of trouble.
> 
> Ok to commit to 4.6?
> 
> What about splitting multilibs? Is this appropriate for 4.7?
> 
> Johann
> 
>       PR target/51002
>       * config/avr/libgcc.S (__prologue_saves__, __epilogue_restores__):
>       Enclose parts using __SP_H__ in defined (__AVR_HAVE_8BIT_SP__).
>       Add FIXME comments.
>       * config/avr/avr.md (movhi_sp_r_irq_off, movhi_sp_r_irq_on): Set
>       insn condition to !AVR_HAVE_8BIT_SP.
>       * config/avr/avr.c (output_movhi): "clr%B0" instead of "in
>       %B0,__SP_H__" if AVR_HAVE_8BIT_SP.
>       (avr_file_start): Only print "__SP_H__ = 0x3e" if !AVR_HAVE_8BIT_SP.
> 

Dropping this patch...

There is ATtiny4313 (and maybe others) that have 8-bit SP and 0x100 RAM.
As RAM starts at 0x60, I wonder what the meaning of SP is?
Is it RAM-address % 0x100? Or offset to 0x60? Maybe Eric can clarify this?

The sequence to read SP would then be something like

IN  %A0, __SP_L__
CPI %A0, 0x60
SBC %B0, %B0
NEG %B0

to reconstruct the hight part in the first case and

IN  %A0, __SP_L__
CPI %A0, 0xA0
SBC %B0, %B0
INC %B0

the the second. It might even need more instructions because CPI need D-reg but
in movhi there is just general reg.

Moreover, the data sheet just mentions SP_L but not SP_H. Yet the sample
program from above disassembles to

...
0000002a <__ctors_end>:
  2a:   11 24           eor     r1, r1
  2c:   1f be           out     0x3f, r1        ; 63
  2e:   cf e5           ldi     r28, 0x5F       ; 95
  30:   d1 e0           ldi     r29, 0x01       ; 1
  32:   de bf           out     0x3e, r29       ; 62
  34:   cd bf           out     0x3d, r28       ; 61
...

i.e. start-up code from avr-libc is initializing 0x3e (SP_H) with 1.

Is this bug in avr-libc or typo in the manual? The "AVR538: Migrating from
ATtiny2313 to ATtiny4313" application note does not address this either.

Johann

Reply via email to