初始提交
This commit is contained in:
66
rom/riscv3/romlib/c_lib/src/machine/riscv/memcpy.c
Normal file
66
rom/riscv3/romlib/c_lib/src/machine/riscv/memcpy.c
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void* memcpy(void* aa, const void* bb, size_t n)
|
||||
{
|
||||
#define BODY(a, b, t) { \
|
||||
t tt = *b; \
|
||||
a++, b++; \
|
||||
*(a-1) = tt; \
|
||||
}
|
||||
|
||||
char* a = (char*)aa;
|
||||
const char* b = (const char*)bb;
|
||||
char* end = a+n;
|
||||
uintptr_t msk = sizeof(long)-1;
|
||||
if (__builtin_expect(((uintptr_t)a & msk) != ((uintptr_t)b & msk) || n < sizeof(long), 0))
|
||||
{
|
||||
small:
|
||||
if (__builtin_expect(a < end, 1))
|
||||
while (a < end)
|
||||
BODY(a, b, char);
|
||||
return aa;
|
||||
}
|
||||
|
||||
if (__builtin_expect(((uintptr_t)a & msk) != 0, 0))
|
||||
while ((uintptr_t)a & msk)
|
||||
BODY(a, b, char);
|
||||
|
||||
long* la = (long*)a;
|
||||
const long* lb = (const long*)b;
|
||||
long* lend = (long*)((uintptr_t)end & ~msk);
|
||||
|
||||
if (__builtin_expect(la < lend-8, 0))
|
||||
{
|
||||
while (la < lend-8)
|
||||
{
|
||||
long b0 = *lb++;
|
||||
long b1 = *lb++;
|
||||
long b2 = *lb++;
|
||||
long b3 = *lb++;
|
||||
long b4 = *lb++;
|
||||
long b5 = *lb++;
|
||||
long b6 = *lb++;
|
||||
long b7 = *lb++;
|
||||
long b8 = *lb++;
|
||||
*la++ = b0;
|
||||
*la++ = b1;
|
||||
*la++ = b2;
|
||||
*la++ = b3;
|
||||
*la++ = b4;
|
||||
*la++ = b5;
|
||||
*la++ = b6;
|
||||
*la++ = b7;
|
||||
*la++ = b8;
|
||||
}
|
||||
}
|
||||
|
||||
while (la < lend)
|
||||
BODY(la, lb, long);
|
||||
|
||||
a = (char*)la;
|
||||
b = (const char*)lb;
|
||||
if (__builtin_expect(a < end, 0))
|
||||
goto small;
|
||||
return aa;
|
||||
}
|
||||
85
rom/riscv3/romlib/c_lib/src/machine/riscv/memset.S
Normal file
85
rom/riscv3/romlib/c_lib/src/machine/riscv/memset.S
Normal file
@@ -0,0 +1,85 @@
|
||||
.text
|
||||
.global memset
|
||||
memset:
|
||||
li a6, 15
|
||||
move a4, a0
|
||||
bleu a2, a6, .Ltiny
|
||||
and a5, a4, 15
|
||||
bnez a5, .Lmisaligned
|
||||
|
||||
.Laligned:
|
||||
bnez a1, .Lwordify
|
||||
|
||||
.Lwordified:
|
||||
and a3, a2, ~15
|
||||
and a2, a2, 15
|
||||
add a3, a3, a4
|
||||
|
||||
#if __riscv_xlen == 64
|
||||
1:sd a1, 0(a4)
|
||||
sd a1, 8(a4)
|
||||
#else
|
||||
1:sw a1, 0(a4)
|
||||
sw a1, 4(a4)
|
||||
sw a1, 8(a4)
|
||||
sw a1, 12(a4)
|
||||
#endif
|
||||
add a4, a4, 16
|
||||
bltu a4, a3, 1b
|
||||
|
||||
bnez a2, .Ltiny
|
||||
ret
|
||||
|
||||
.Ltiny:
|
||||
sub a3, a6, a2
|
||||
sll a3, a3, 2
|
||||
1:auipc t0, %pcrel_hi(.Ltable)
|
||||
add a3, a3, t0
|
||||
.option push
|
||||
.option norvc
|
||||
.Ltable_misaligned:
|
||||
jr a3, %pcrel_lo(1b)
|
||||
.Ltable:
|
||||
sb a1,14(a4)
|
||||
sb a1,13(a4)
|
||||
sb a1,12(a4)
|
||||
sb a1,11(a4)
|
||||
sb a1,10(a4)
|
||||
sb a1, 9(a4)
|
||||
sb a1, 8(a4)
|
||||
sb a1, 7(a4)
|
||||
sb a1, 6(a4)
|
||||
sb a1, 5(a4)
|
||||
sb a1, 4(a4)
|
||||
sb a1, 3(a4)
|
||||
sb a1, 2(a4)
|
||||
sb a1, 1(a4)
|
||||
sb a1, 0(a4)
|
||||
.option pop
|
||||
ret
|
||||
|
||||
.Lwordify:
|
||||
and a1, a1, 0xFF
|
||||
sll a3, a1, 8
|
||||
or a1, a1, a3
|
||||
sll a3, a1, 16
|
||||
or a1, a1, a3
|
||||
#if __riscv_xlen == 64
|
||||
sll a3, a1, 32
|
||||
or a1, a1, a3
|
||||
#endif
|
||||
j .Lwordified
|
||||
|
||||
.Lmisaligned:
|
||||
sll a3, a5, 2
|
||||
1:auipc t0, %pcrel_hi(.Ltable_misaligned)
|
||||
add a3, a3, t0
|
||||
mv t0, ra
|
||||
jalr a3, %pcrel_lo(1b)
|
||||
mv ra, t0
|
||||
|
||||
add a5, a5, -16
|
||||
sub a4, a4, a5
|
||||
add a2, a2, a5
|
||||
bleu a2, a6, .Ltiny
|
||||
j .Laligned
|
||||
135
rom/riscv3/romlib/c_lib/src/machine/riscv/strcmp.S
Normal file
135
rom/riscv3/romlib/c_lib/src/machine/riscv/strcmp.S
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <sys/asm.h>
|
||||
|
||||
#if BYTE_ORDER != LITTLE_ENDIAN
|
||||
# error
|
||||
#endif
|
||||
|
||||
.text
|
||||
.globl strcmp
|
||||
strcmp:
|
||||
or a4, a0, a1
|
||||
li t2, -1
|
||||
and a4, a4, SZREG-1
|
||||
bnez a4, .Lmisaligned
|
||||
|
||||
#if SZREG == 4
|
||||
li t3, 0x7f7f7f7f
|
||||
#else
|
||||
ld t3, mask
|
||||
#endif
|
||||
|
||||
.macro check_one_word i n
|
||||
REG_L a2, \i*SZREG(a0)
|
||||
REG_L a3, \i*SZREG(a1)
|
||||
|
||||
and t0, a2, t3
|
||||
or t1, a2, t3
|
||||
add t0, t0, t3
|
||||
or t0, t0, t1
|
||||
|
||||
bne t0, t2, .Lnull\i
|
||||
.if \i+1-\n
|
||||
bne a2, a3, .Lmismatch
|
||||
.else
|
||||
add a0, a0, \n*SZREG
|
||||
add a1, a1, \n*SZREG
|
||||
beq a2, a3, .Lloop
|
||||
# fall through to .Lmismatch
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro foundnull i n
|
||||
.ifne \i
|
||||
.Lnull\i:
|
||||
add a0, a0, \i*SZREG
|
||||
add a1, a1, \i*SZREG
|
||||
.ifeq \i-1
|
||||
.Lnull0:
|
||||
.endif
|
||||
bne a2, a3, .Lmisaligned
|
||||
li a0, 0
|
||||
ret
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.Lloop:
|
||||
# examine full words at a time, favoring strings of a couple dozen chars
|
||||
#if __riscv_xlen == 32
|
||||
check_one_word 0 5
|
||||
check_one_word 1 5
|
||||
check_one_word 2 5
|
||||
check_one_word 3 5
|
||||
check_one_word 4 5
|
||||
#else
|
||||
check_one_word 0 3
|
||||
check_one_word 1 3
|
||||
check_one_word 2 3
|
||||
#endif
|
||||
# backwards branch to .Lloop contained above
|
||||
|
||||
.Lmismatch:
|
||||
# words don't match, but a2 has no null byte.
|
||||
#if __riscv_xlen == 64
|
||||
sll a4, a2, 48
|
||||
sll a5, a3, 48
|
||||
bne a4, a5, .Lmismatch_upper
|
||||
sll a4, a2, 32
|
||||
sll a5, a3, 32
|
||||
bne a4, a5, .Lmismatch_upper
|
||||
#endif
|
||||
sll a4, a2, 16
|
||||
sll a5, a3, 16
|
||||
bne a4, a5, .Lmismatch_upper
|
||||
|
||||
srl a4, a2, 8*SZREG-16
|
||||
srl a5, a3, 8*SZREG-16
|
||||
sub a0, a4, a5
|
||||
and a1, a0, 0xff
|
||||
bnez a1, 1f
|
||||
ret
|
||||
|
||||
.Lmismatch_upper:
|
||||
srl a4, a4, 8*SZREG-16
|
||||
srl a5, a5, 8*SZREG-16
|
||||
sub a0, a4, a5
|
||||
and a1, a0, 0xff
|
||||
bnez a1, 1f
|
||||
ret
|
||||
|
||||
1:and a4, a4, 0xff
|
||||
and a5, a5, 0xff
|
||||
sub a0, a4, a5
|
||||
ret
|
||||
|
||||
.Lmisaligned:
|
||||
# misaligned
|
||||
lbu a2, 0(a0)
|
||||
lbu a3, 0(a1)
|
||||
add a0, a0, 1
|
||||
add a1, a1, 1
|
||||
bne a2, a3, 1f
|
||||
bnez a2, .Lmisaligned
|
||||
|
||||
1:
|
||||
sub a0, a2, a3
|
||||
ret
|
||||
|
||||
# cases in which a null byte was detected
|
||||
#if __riscv_xlen == 32
|
||||
foundnull 0 5
|
||||
foundnull 1 5
|
||||
foundnull 2 5
|
||||
foundnull 3 5
|
||||
foundnull 4 5
|
||||
#else
|
||||
foundnull 0 3
|
||||
foundnull 1 3
|
||||
foundnull 2 3
|
||||
#endif
|
||||
|
||||
#if SZREG == 8
|
||||
.section .srodata.cst8,"aM",@progbits,8
|
||||
.align 3
|
||||
mask:
|
||||
.dword 0x7f7f7f7f7f7f7f7f
|
||||
#endif
|
||||
53
rom/riscv3/romlib/c_lib/src/machine/riscv/strcpy.c
Normal file
53
rom/riscv3/romlib/c_lib/src/machine/riscv/strcpy.c
Normal file
@@ -0,0 +1,53 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
char* strcpy(char* dst, const char* src)
|
||||
{
|
||||
char* dst0 = dst;
|
||||
|
||||
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
|
||||
int misaligned = ((uintptr_t)dst | (uintptr_t)src) & (sizeof(long)-1);
|
||||
if (__builtin_expect(!misaligned, 1))
|
||||
{
|
||||
long* ldst = (long*)dst;
|
||||
const long* lsrc = (const long*)src;
|
||||
|
||||
while (!__libc_detect_null(*lsrc))
|
||||
*ldst++ = *lsrc++;
|
||||
|
||||
dst = (char*)ldst;
|
||||
src = (const char*)lsrc;
|
||||
|
||||
char c0 = src[0];
|
||||
char c1 = src[1];
|
||||
char c2 = src[2];
|
||||
if (!(*dst++ = c0)) return dst0;
|
||||
if (!(*dst++ = c1)) return dst0;
|
||||
char c3 = src[3];
|
||||
if (!(*dst++ = c2)) return dst0;
|
||||
if (sizeof(long) == 4) goto out;
|
||||
char c4 = src[4];
|
||||
if (!(*dst++ = c3)) return dst0;
|
||||
char c5 = src[5];
|
||||
if (!(*dst++ = c4)) return dst0;
|
||||
char c6 = src[6];
|
||||
if (!(*dst++ = c5)) return dst0;
|
||||
if (!(*dst++ = c6)) return dst0;
|
||||
|
||||
out:
|
||||
*dst++ = 0;
|
||||
return dst0;
|
||||
}
|
||||
#endif /* not PREFER_SIZE_OVER_SPEED */
|
||||
|
||||
char ch;
|
||||
do
|
||||
{
|
||||
ch = *src;
|
||||
src++;
|
||||
dst++;
|
||||
*(dst-1) = ch;
|
||||
} while(ch);
|
||||
|
||||
return dst0;
|
||||
}
|
||||
42
rom/riscv3/romlib/c_lib/src/machine/riscv/strlen.c
Normal file
42
rom/riscv3/romlib/c_lib/src/machine/riscv/strlen.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
size_t strlen(const char* str)
|
||||
{
|
||||
const char* start = str;
|
||||
|
||||
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
|
||||
while (*str++)
|
||||
;
|
||||
return str - start - 1;
|
||||
#else
|
||||
if (__builtin_expect((uintptr_t)str & (sizeof(long)-1), 0)) do
|
||||
{
|
||||
char ch = *str;
|
||||
str++;
|
||||
if (!ch)
|
||||
return str - start - 1;
|
||||
} while ((uintptr_t)str & (sizeof(long)-1));
|
||||
|
||||
unsigned long* ls = (unsigned long*)str;
|
||||
while (!__libc_detect_null(*ls++))
|
||||
;
|
||||
asm volatile ("" : "+r"(ls)); /* prevent "optimization" */
|
||||
|
||||
str = (const char*)ls;
|
||||
size_t ret = str - start, sl = sizeof(long);
|
||||
|
||||
char c0 = str[0-sl], c1 = str[1-sl], c2 = str[2-sl], c3 = str[3-sl];
|
||||
if (c0 == 0) return ret + 0 - sl;
|
||||
if (c1 == 0) return ret + 1 - sl;
|
||||
if (c2 == 0) return ret + 2 - sl;
|
||||
if (sl == 4 || c3 == 0) return ret + 3 - sl;
|
||||
|
||||
c0 = str[4-sl], c1 = str[5-sl], c2 = str[6-sl], c3 = str[7-sl];
|
||||
if (c0 == 0) return ret + 4 - sl;
|
||||
if (c1 == 0) return ret + 5 - sl;
|
||||
if (c2 == 0) return ret + 6 - sl;
|
||||
|
||||
return ret + 7 - sl;
|
||||
#endif /* not PREFER_SIZE_OVER_SPEED */
|
||||
}
|
||||
46
rom/riscv3/romlib/c_lib/src/soft-fp/soft-fp.c
Normal file
46
rom/riscv3/romlib/c_lib/src/soft-fp/soft-fp.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern int32_t iot_printf(const char *fmt, ...);
|
||||
|
||||
double soft_fp_add(double a, double b)
|
||||
{
|
||||
return a*b;
|
||||
}
|
||||
|
||||
double soft_fp_sub(double a, double b)
|
||||
{
|
||||
return a-b;
|
||||
}
|
||||
|
||||
double soft_fp_mul(double a, double b)
|
||||
{
|
||||
return a*b;
|
||||
}
|
||||
|
||||
double soft_fp_div(double a, double b)
|
||||
{
|
||||
return a/b;
|
||||
}
|
||||
|
||||
|
||||
void double_soft_fp_op()
|
||||
{
|
||||
double a = (double)(*((float*)0xffd8000));
|
||||
double b = (double)(*((float*)0xffd9000));
|
||||
double c;
|
||||
double d;
|
||||
double e;
|
||||
double f;
|
||||
|
||||
c = soft_fp_add(a, b);
|
||||
d = soft_fp_sub(a, b);
|
||||
e = soft_fp_mul(a, b);
|
||||
f = soft_fp_div(a, b);
|
||||
|
||||
iot_printf("%f\n",a);
|
||||
iot_printf("%f\n",b);
|
||||
iot_printf("%f\n",c);
|
||||
iot_printf("%f\n",d);
|
||||
iot_printf("%f\n",e);
|
||||
iot_printf("%f\n",(float)f);
|
||||
}
|
||||
Reference in New Issue
Block a user