[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
.text
.global memcpy_EP
.type memcpy_EP, @function
memcpy_EP:
out _SFR_IO_ADDR(RAMPZ), src_3
movw r30, src_lo ; Z
movw r26, dst_lo ; X
rjmp .memcpy_EP_start
.memcpy_EP_loop:
elpm r0, Z+
st X+, r0
.memcpy_EP_start:
subi len_lo, lo8(1)
sbci len_hi, hi8(1)
brcc .memcpy_EP_loop
; return dest (unchanged)
ret
.memcpy_P_end:
.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
http://www.DaveHylands.com/