[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Does anybody have a variant of memcpy that uses ELPM?

From: Dave Hylands
Subject: Re: [avr-gcc-list] Does anybody have a variant of memcpy that uses ELPM?
Date: Thu, 19 Jan 2006 11:06:13 -0800

Hi Eric,

> > Before I go off and reinvent the wheel, I figured I'd ask if anybody
> > has a variant of memcpy which uses the ELPM instruction (as I
> > understand it, memcpy_P uses LPM which doesn't work for me).

> I'm sorry, no I don't have one. It shouldn't be too hard to grab a copy
> of the source from avr-libc and modify it to suit your needs.
> But now that I'm thinking of it. Would you be willing to submit a new
> Task Tracker in the avr-libc project about this?:
> <http://savannah.nongnu.org/task/?group=avr-libc>
> This is a good idea to have in avr-libc and I don't want the issue to
> get lost.

Sure. I actually implemented my own using the memcpy_P.S as a template.

I also created an inline assembly function which will grab the 32 bit
address of an arbitrary symbol. I've included both in this email, and
I'll throw them in the bug report as well.

-----Start of memcpy_EP.S (minus the GPL header) -----
#include <avr/io.h>

// extern void *memcpy_EP( void *dst, uint32_t src, size_t len );

#define dst_hi  r25
#define dst_lo  r24
#define src_hi  r23     ; Not actually used (s/b always zero)
#define src_3   r22
#define src_2   r21
#define src_lo  r20
#define len_hi  r19
#define len_lo  r18

        .global memcpy_EP
        .type   memcpy_EP, @function

        out     _SFR_IO_ADDR(RAMPZ), src_3
        movw    r30, src_lo     ; Z
        movw    r26, dst_lo     ; X
        rjmp    .memcpy_EP_start

        elpm    r0, Z+
            st      X+, r0

            subi        len_lo, lo8(1)
            sbci        len_hi, hi8(1)

            brcc        .memcpy_EP_loop

; return dest (unchanged)

            .size   memcpy_EP, .memcpy_EP_end - memcpy_EP

-----End of memcpy_EP.S -----

// The addr32 macro returns a byte address of a symbol located anywhere in
// the 128K space of the ATMega128.

#define addr32(symbol)        \
({                                          \
    uint32_t __result;                      \
    __asm__                                 \
    (                                       \
        "ldi %A0, lo8(pm(" #symbol "))\n\t" \
        "ldi %B0, hi8(pm(" #symbol "))\n\t" \
        "eor %C0, %C0"              "\n\t"  \
        "eor %D0, %D0"              "\n\t"  \
        "add %A0, %A0"              "\n\t"  \
        "adc %B0, %B0"              "\n\t"  \
        "adc %C0, %C0"              "\n\t"  \
        : "=r" (__result)                   \
    );                                      \
    __result;                               \

Dave Hylands
Vancouver, BC, Canada

reply via email to

[Prev in Thread] Current Thread [Next in Thread]