Перенос на новую организацию GONEC

This commit is contained in:
cfif 2025-01-24 13:22:33 +03:00
commit 705c7570d3
5 changed files with 281 additions and 0 deletions

14
fastfunc.h Normal file
View File

@ -0,0 +1,14 @@
//
// Created by cfif on 08.06.23.
//
#ifndef FASTFUNC_H
#define FASTFUNC_H
#include <stdlib.h>
void *memcpy_fast(void *dst0, const void *src0, size_t len0);
void *memmove_fast(void *dst_void, const void *src_void, size_t length);
void memcpy32 (void* dest, const void* src, size_t size);
#endif //FASTFUNC_H

94
memcpy-fast.c Executable file
View File

@ -0,0 +1,94 @@
/*
FUNCTION
<<memcpy>>---copy memory regions
ANSI_SYNOPSIS
#include <string.h>
void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
TRAD_SYNOPSIS
void *memcpy(<[out]>, <[in]>, <[n]>
void *<[out]>;
void *<[in]>;
size_t <[n]>;
DESCRIPTION
This function copies <[n]> bytes from the memory region
pointed to by <[in]> to the memory region pointed to by
<[out]>.
If the regions overlap, the behavior is undefined.
RETURNS
<<memcpy>> returns a pointer to the first byte of the <[out]>
region.
PORTABILITY
<<memcpy>> is ANSI C.
<<memcpy>> requires no supporting OS subroutines.
QUICKREF
memcpy ansi pure
*/
#include <fastfunc.h>
#undef memcpy
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof (long) << 2)
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof (long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
void *
memcpy_fast(void *dst0, const void *src0, size_t len0)
{
unsigned char *dst = dst0;
const unsigned char *src = src0;
long *aligned_dst;
const long *aligned_src;
int len = len0;
/* If the size is small, or either SRC or DST is unaligned,
then punt into the byte copy loop. This should be rare. */
if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* Copy 4X long words at a time if possible. */
while (len >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (len >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
len -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
dst = (unsigned char*)aligned_dst;
src = (unsigned char*)aligned_src;
}
while (len--)
*dst++ = *src++;
return dst0;
}

50
memcpy32.s Normal file
View File

@ -0,0 +1,50 @@
.syntax unified
.cpu cortex-m4
.fpu softvfp
.thumb
.global memcpy32
.type memcpy32, %function
memcpy32:
push {r4, r5, r6, r7, r8, r9, r10, r11}
bics r11, r2, #31
beq 2f
add r11, r0
1: ldmia r1!, { r3, r4, r5, r6, r7, r8, r9, r10 }
stmia r0!, { r3, r4, r5, r6, r7, r8, r9, r10 }
cmp r0, r11
bne 1b
2:
tst r2, #16
itt NE
ldmiane r1!, { r3, r4, r5, r6 }
stmiane r0!, { r3, r4, r5, r6 }
tst r2, #8
itt NE
ldrdne r3, r4, [r1], #+8
strdne r3, r4, [r0], #+8
tst r2, #4
itt NE
ldrne r3, [r1], #+4
strne r3, [r0], #+4
tst r2, #2
itt NE
ldrhne r3, [r1], #+2
strhne r3, [r0], #+2
tst r2, #1
itt NE
ldrbne r3, [r1], #+1
strbne r3, [r0], #+1
pop {r4, r5, r6, r7, r8, r9, r10, r11}
bx lr

112
memmove-fast.c Executable file
View File

@ -0,0 +1,112 @@
/*
FUNCTION
<<memmove>>---move possibly overlapping memory
INDEX
memmove
ANSI_SYNOPSIS
#include <string.h>
void *memmove(void *<[dst]>, const void *<[src]>, size_t <[length]>);
TRAD_SYNOPSIS
#include <string.h>
void *memmove(<[dst]>, <[src]>, <[length]>)
void *<[dst]>;
void *<[src]>;
size_t <[length]>;
DESCRIPTION
This function moves <[length]> characters from the block of
memory starting at <<*<[src]>>> to the memory starting at
<<*<[dst]>>>. <<memmove>> reproduces the characters correctly
at <<*<[dst]>>> even if the two areas overlap.
RETURNS
The function returns <[dst]> as passed.
PORTABILITY
<<memmove>> is ANSI C.
<<memmove>> requires no supporting OS subroutines.
QUICKREF
memmove ansi pure
*/
#include <fastfunc.h>
#undef memmove
/* Nonzero if either X or Y is not aligned on a "long" boundary. */
#define UNALIGNED(X, Y) \
(((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof (long) << 2)
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof (long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
void *
memmove_fast(void *dst_void, const void *src_void, size_t length)
{
unsigned char *dst = dst_void;
const unsigned char *src = src_void;
long *aligned_dst;
const long *aligned_src;
int len = length;
if (src < dst && dst < src + len)
{
/* Destructive overlap...have to copy backwards */
src += len;
dst += len;
while (len--)
{
*--dst = *--src;
}
}
else
{
/* Use optimizing algorithm for a non-destructive copy to closely
match memcpy. If the size is small or either SRC or DST is unaligned,
then punt into the byte copy loop. This should be rare. */
if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
{
aligned_dst = (long*)dst;
aligned_src = (long*)src;
/* Copy 4X long words at a time if possible. */
while (len >= BIGBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
*aligned_dst++ = *aligned_src++;
len -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (len >= LITTLEBLOCKSIZE)
{
*aligned_dst++ = *aligned_src++;
len -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
dst = (unsigned char*)aligned_dst;
src = (unsigned char*)aligned_src;
}
while (len--)
{
*dst++ = *src++;
}
}
return dst_void;
}

11
modular.json Normal file
View File

@ -0,0 +1,11 @@
{
"cmake": {
"inc_dirs": [
"./"
],
"srcs": [
"./**.c",
"**.s"
]
}
}