diff --git a/lib_nn/src/asm/lookup8.S b/lib_nn/src/asm/lookup8.S index a3ab9e00..b9d305bc 100644 --- a/lib_nn/src/asm/lookup8.S +++ b/lib_nn/src/asm/lookup8.S @@ -103,5 +103,103 @@ FUNCTION_NAME: #endif +#if defined(__VX4B__) + +/* +void lookup8_asm( + uint8_t* Y, + const uint8_t* X, + const uint8_t* lut, + const unsigned elm_start, + const unsigned elm_count); +*/ + +#define FUNCTION_NAME lookup8_asm + +.p2align 1 +.globl FUNCTION_NAME +.type FUNCTION_NAME,@function + +#define STACK_X18 (0) +#define STACK_X19 (STACK_X18 + 4) +#define STACK_X20 (STACK_X19 + 4) +#define STACK_X21 (STACK_X20 + 4) +#define STACK_X22 (STACK_X21 + 4) +#define STACK_X23 (STACK_X22 + 4) +#define STACK_X24 (STACK_X23 + 4) +#define STACK_VEC1_TMP (STACK_X24 + 4) +#define STACK_RA (STACK_VEC1_TMP + 32) +#define NSTACKBYTES (STACK_RA + 4) +#define ROUND_UP(X, Y) (((X+Y-1)/Y)*Y) + +#define out_data x10 +#define in_data x11 +#define lut x12 +#define start x13 +#define count x18 +#define mask x19 +#define counter x20 +#define thirty_two x21 +#define vec1_tmp x22 + +FUNCTION_NAME: + + { xm.entsp ROUND_UP(NSTACKBYTES, 16) ; xm.nop } + xm.stdsp x18, x19, 0*8 + xm.stdsp x20, x21, 1*8 + xm.stdsp x22, x23, 2*8 + sw x24, 3*8(sp) + addi count, x14, 0 + add out_data, out_data, start + add in_data, in_data, start + addi vec1_tmp, sp, STACK_VEC1_TMP + xm.mkmski mask, 32 + li thirty_two, 32 + // out_data substract 32 first for optimize in the loop + sub out_data, out_data, thirty_two + + // Set VPU to 8-bit mode + li x28, 512 + { xm.vsetc x28 ; xm.shri counter, count, 5 } + xm.vldc lut + + FUNCTION_NAME.loop: + { xm.vldr in_data ; add in_data, in_data, thirty_two } + xm.vlookup lut, 0, 1 + xm.vlookup lut, 1, 2 + xm.vlookup lut, 2, 3 + xm.vlookup lut, 3, 4 + xm.vlookup lut, 4, 5 + xm.vlookup lut, 5, 6 + xm.vlookup lut, 6, 7 + xm.vlookup lut, 7, 0 + bnez counter, FUNCTION_NAME.save + // In last loop - make mask for remaining elements + xm.zexti count, 4 + xm.mkmsk mask, count + + FUNCTION_NAME.save: + { xm.vstd vec1_tmp ; xm.nop } + { xm.vldr vec1_tmp ; add out_data, out_data, thirty_two } + xm.vstrpv out_data, mask + { addi counter, counter, -1 ; xm.bt counter, FUNCTION_NAME.loop } + + + xm.lddsp x18, x19, 0*8 + xm.lddsp x20, x21, 1*8 + xm.lddsp x22, x23, 2*8 + lw x24, 3*8(sp) + + {xm.retsp ROUND_UP(NSTACKBYTES, 16); xm.nop} + +.size FUNCTION_NAME, . -FUNCTION_NAME +.resource_const FUNCTION_NAME, "stack_frame_bytes", ROUND_UP(NSTACKBYTES, 16) +.resource_list_empty FUNCTION_NAME, "callees" +.resource_list_empty FUNCTION_NAME, "tail_callees" +.resource_list_empty FUNCTION_NAME, "parallel_callees" + +#endif + + diff --git a/lib_nn/src/c/nn_operator.c b/lib_nn/src/c/nn_operator.c index c16837d0..0e950dfe 100644 --- a/lib_nn/src/c/nn_operator.c +++ b/lib_nn/src/c/nn_operator.c @@ -139,6 +139,15 @@ void lookup8_ref(uint8_t *Y, const uint8_t *X, const uint8_t *lut, } } +#if defined(__XS3A__) || defined(__VX4B__) +void lookup8_asm( + uint8_t* Y, + const uint8_t* X, + const uint8_t* lut, + const unsigned elm_start, + const unsigned elm_count); +#endif + #ifdef NN_USE_REF void requantize_16_to_8(int8_t *y, const int16_t *x, const unsigned elm_start, const unsigned elm_count) { @@ -148,10 +157,12 @@ void requantize_16_to_8(int8_t *y, const int16_t *x, const unsigned elm_start, void lookup8(uint8_t *Y, const uint8_t *X, const uint8_t *lut, const unsigned elm_start, const unsigned elm_count) { -#if defined(NN_USE_REF) || defined(__VX4A__) || defined(__VX4B__) +#if defined(NN_USE_REF) lookup8_ref(Y, X, lut, elm_start, elm_count); -#elif defined(__XS3A__) +#elif defined(__XS3A__) || defined(__VX4B__) lookup8_asm(Y, X, lut, elm_start, elm_count); +#else + lookup8_ref(Y, X, lut, elm_start, elm_count); #endif // NN_USE_REF }